博客地址 :http://blog.csdn.net/shulianghan/article/details/40737419

代码下载 : Android 应用 Application 经典用法;

-- Github :https://github.com/han1202012/ApplicationDemo

-- CSDN :http://download.csdn.net/detail/han1202012/8127247




一. Application 分析



1. Application 简介



(1) Application 概念


Application 概念 : Application 属于组件范畴;

-- 本质 : Application 与 四大组件 一样也属于 Android 中的组件;

-- 作用 : 用于存储系统 和 用户定义的全局信息;

-- Application 创建 : 应用开始运行时创建 Application 对象, 可以自定义, 也可以让系统自动创建;

-- Application 单例性 : 每个应用只创建一个 Application 对象, 该类属于单例模式;

-- Application 生命周期 : Application 生命周期 从应用启动开始 到 应用退出结束, 与应用的生命周期是相同的;

-- Application 作用 : 在任何组件中调用 getApplication() 或者通过 Context 对象调用 getApplicationContext() 方法获取的 Application 对象都是相同的, 因此可以使用 Application 进行数据共享, 数据缓存操作;



(2) Application 与 全局变量


Application 与 全局变量 :

-- 基本作用 : Application 在 Android 中是为了 保存全局变量 而设计的类;

-- Android 全局变量定义 : 在 Android 中可以不使用 public static 定义全局变量, 定义在 Application 中的普通变量 在Android应用中可以当作全局变量使用;



(3) Application 使用方法


Application 使用方法 :

-- 自定义 Application : 自定义一个 class 类, 继承 android.app.Application 类;

-- 配置 Application : 在 AndroidManifest.xml 中配置 Application;

--获取 Application : 在组件类(Activity, Service 等)中直接调用 getApplication() 方法即可, 在普通类中调用 Context 的 getApplicationContext() 方法;



2. Application 生命周期 及 对应方法



(1) onCreate()


onCreate() 方法简介 : 该方法是 Android 程序的入口;

-- 执行时机 : 该方法在应用创建时自动回调;

-- 注意 : 在父类 Application 中, onCreate() 方法方法体是空的, 这里可以不用执行 super.onCreate()方法;


关于程序入口 :

-- Android 程序入口 : Android 程序入口是 Application, 并不是 Activity, 因为有的 应用是没有 Activity 的;

-- Java 和 C 程序入口 : 这两种语言的程序入口是工程中的 main() 函数;



(2) onLowMemory()


onLowMemory() 方法简介 :

-- 调用时机 : 在内存不足时会回调该方法;

-- 重写方法 : 重写时需要执行父类方法 super.onLowMemory(), 同时根据本应用特点, 释放掉一些不必要的数据;



(3) onTerminate()


onTerminate() 方法简介 :

-- 调用时机 : 只有在模拟器中终止程序时才会回调该方法, 在 Android 真机中是不会回调该方法的;

-- 注意 : Application 的 onTerminate() 方法体是空的, 这里不许要执行父类的方法 super.onTerminate();



(4)onConfigurationChanged()


onConfigurationChanged() 方法简介 :

-- 调用时机 : 配置改变时回调这个方法;



(5) Application 代码分析


Application 相关代码 :

    /**     * Called when the application is starting, before any other application     * objects have been created.  Implementations should be as quick as     * possible (for example using lazy initialization of state) since the time     * spent in this function directly impacts the performance of starting the     * first activity, service, or receiver in a process.     * If you override this method, be sure to call super.onCreate().     */    public void onCreate() {    }    /**     * This method is for use in emulated process environments.  It will     * never be called on a production Android device, where processes are     * removed by simply killing them; no user code (including this callback)     * is executed when doing so.     */    public void onTerminate() {    }    public void onConfigurationChanged(Configuration newConfig) {        Object[] callbacks = collectComponentCallbacks();        if (callbacks != null) {            for (int i=0; i<callbacks.length; i++) {                ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);            }        }    }    public void onLowMemory() {        Object[] callbacks = collectComponentCallbacks();        if (callbacks != null) {            for (int i=0; i<callbacks.length; i++) {                ((ComponentCallbacks)callbacks[i]).onLowMemory();            }        }    }





3. Application 使用场景 1 --> 组件间的数据传递



(1) 使用 Application 传递数据


Application 媒介传递数据方式 :

-- Appliction 集合 : 在 Application 中维护一个集合, 创建一个 HashMap 成员变量, 键是字符串, 值是 Object 对象, 这样 这个 HashMap 可以存储任何类型的对象;

-- 共享过程 : Activity A 将数据存储到 HashMap 中, 将 键 通过 Intent 的 Bundle 传递给 Activity B, 之后在 Activity B 中取出对象, 并将 HashMap 中的对象删除;

-- 适用范围 : 如果跳转的两个 Activity 在同一个 应用 中, 可以使用这种方法;



(2) 传统传递数据方式


传统数据传递 :Activity A 跳转到 Activity B;

-- 实体类 Bean 处理 : bean 实体类必须实现Serializable或者Parcellable接口, 才可以将实体类 bean 对象放入 Intent 的 Bundle 中;

-- 数据传递过程 : 在 Activity A 中将 实现了 Serializable 或者 Parcellable 接口的实体类对象放入 Intent 的 Bundle 中, 跳转到 Activity B;



4. Application 使用场景 2 --> 应用中的数据缓存


Application 缓存数据 :

-- 缓存少量数据 : 从互联网获取的少量数据可以直接存放在 Application 中用于数据缓存的 HashMap 中;

-- 缓存大量数据 : 如果缓存 数据 或者 文件, 可以将文件缓存到本地, 然后在 Application 中缓存一个 文件路径字符串即可;

-- 释放缓存 : 在 onLowMemory() 方法中可以释放这些缓存, 因为这些缓存可有可无, 这里为了性能牺牲访问速度;


数据传递, 缓存 Application 示例 :

package cn.org.octopus.application;import java.util.HashMap;import java.util.Map;import android.app.Application;public class MyApplication extends Application {/** 用于数据传递的 Map 集合 */private Map<String, Object> transferMap;/** 用于缓存数据的 Map 集合 */private Map<String, Object> cacheMap; @Overridepublic void onCreate() {super.onCreate();//初始化用于数据传递的 Map 集合transferMap = new HashMap<String, Object>();//初始化用于数据缓存的 Map 集合cacheMap = new HashMap<String, Object>();}/** * 获取数据传递 Map 集合 * @return * 数据传递 Map 集合 */public Map<String, Object> getTransferMap() {return transferMap;}/** * 获取数据缓存 Map 集合 * @return * 数据缓存 Map 集合 */public Map<String, Object> getCacheMap() {return cacheMap;}}


5. Application 与 内存泄漏



(1) Application 内存泄漏


Application 内存分析 :

-- 注意存放对象 : Application 中如果保存了一些大的对象, 例如 Activity 等组件, 如果没有释放, 将会引起很多内存泄漏;

-- 内存释放 : 在 Application 中要经常注意释放不许要的对象, 使用完毕后能释放掉的就释放, 在 onLowMemory() 方法中将所有的缓存数据都清空;



(2) Application 尽量不要持有 组件引用


组件持有 Context 对象 :

-- 创建组件 : TextView tv = new TextView(Activity activity), 这样一来 组件持有了 Activity 或者 Context 对象;

-- 组件持久化 : 当将持有 Context的 tv 组件设置为静态 或者 将 tv 组件设置到 Application 中时, tv 的声明周期就变成了整个应用的声明周期了;

-- Context 无法释放 : 此时 当 Activity 退出后, 组件仍然存在, Conetxt 无法释放, 一旦多次访问这个 Activity, 每次都会泄漏 Context 大小的内存;


防止内存泄漏方法 :

-- 组件 : Activity 中的组件的声明周期不要超出 Activity 生命周期;

-- 图片 : 组件使用的 Drawable 对象不要超出 Actiity 声明周期;

-- 线程持有对象 : 不要在线程中持有 Context, 否则在线程执行完毕之前都处于内存泄漏状态;

-- 内部类作用域不要超出 Activity : 如果在 Activity A 中定义了内部类, 不要将这个内部类传递给其它 Activity 等组件, 否则该 Activity A 不能释放, 建议将内部类设置成 static 或者 单独写成一个类;




二. Application 应用层源码分析



1. Application 类结构分析



(1) Application 继承关系


Application 类继承结构:

-- Application 类 :public class Application extends ContextWrapper implements ComponentCallbacks2 ;

-- ContextWrapper 类 :public class ContextWrapper extends Context ;

-- Context 类 :public abstract class Context;

-- ComponentCallbacks2 接口 :public interface ComponentCallbacks2 extends ComponentCallbacks ;

-- ComponentCallbacks 接口 :public interface ComponentCallbacks ;

-- UML 图 :

【Android 应用开发】 Application 使用分析



(2) 相关类介绍


Application 相关类介绍 :

-- Application 类 : 用于存储应用的全局变量;

-- ContextWrapper 类 : 该类是 Context 简单的代理实现, 代表了对另一个 Context 的调用, 在该类的子类中可以重写对应方法改变指定的操作行为;

-- Context 类 : 该 抽象类应用环境的全局信息接口, Android 提供了该抽象类的实现类, 该类用于访问 应用的 资源 和 类 (作用一), 返回 应用的 Actiity, 广播, Intent 等操作的执行结果(作用二);

-- ComponentCallbacks2 接口 : 该接口继承了 ComponentCallbacks, 用于更细粒度的内存管理;

-- ComponentCallbacks 接口 :应用组件的回调接口, 所有的组件都要实现这个接口;



2. CompnentCallbacks 接口


部分源码 : 省略了注释部分, 代码完整;

package android.content;import android.content.res.Configuration;public interface ComponentCallbacks {    void onConfigurationChanged(Configuration newConfig);        void onLowMemory();}



(1)onConfigurationChanged() 方法介绍


方法介绍 : 该方法回调后需要重新加载新配置对应的资源, 如果 Activity 对应配置改变需要 重启组件, 其它组件不用重启;

-- 方法全称 :void onConfigurationChanged(Configuration newConfig);

-- 回调时机: 在组件运行时, 如果发生了设备的配置改变, 就会回调该接口的方法;

-- 重新加载资源 : 当配置改变, 该方法回调后, 需要更新资源, 以找到与新配置匹配的资源, 例如屏幕方向改变了, 需要找 drawable-land (横屏) 或者 drawable-port (竖屏资源);

-- Activity 组件配置改变 : 当 Activity 运行的时候, 如果配置发生改变, 需要进行重新启动, 例如 横屏 切换 竖屏;

-- 其它组件配置改变 : 在 Service 等组件运行时, 配置发生改变, 不需要重新启动;



(2)onLowMemory() 方法介绍


方法介绍 :

-- 方法全称 :void onLowMemory();

-- 回调时机 : 当系统剩余内存比较低的时候, 并且系统想要 清理内存以获取更多内存时 回调该方法;

-- 时间点不确定 : 不能确定方法回调准确的时间点, 大概在所有的后台进行被杀死的时间点 左右 回调该方法, 这个时间点在 服务进程被杀死之前;

-- 避免杀死前台进程 : UI 进程在清理内存时, 是应该避免被杀死的, 这类进程尽量保存;

-- 方法中的建议操作 : 组件实现该方法, 在该方法中建议进行 释放缓存 或者 释放不需要持有的资源, 执行该方法后, 系统会执行 GC 垃圾回收;



3. ComponentCallbacks2 接口


源码示例 : 一部份源码, 省略了注释 和 一部份的 常量;

package android.content;public interface ComponentCallbacks2 extends ComponentCallbacks {    static final int TRIM_MEMORY_COMPLETE = 80;        static final int TRIM_MEMORY_MODERATE = 60;    ... ...    void onTrimMemory(int level);}


(1) onTrimMemory() 方法介绍


方法介绍 :

-- 方法全称 :void onTrimMemory(int level) ;

-- 回调时机 : 当 系统决定要清理一个进程不必要的内存时 回调该方法;

-- 清理内存时机 : 后台进程运行时, 当没有足够的内存去保持这些后台进程运行时, 就会进行内存清理;

-- 内存等级 : 每个等级都有一个对应的内存值, 但是这个内存等级的精确值是无法获取的, 因为随时都有新的中间值会累加上去;



(2) 内存等级常量介绍


LRU list 概念 : 全称 Least Recently Used, 即最近最少使用算法, 用于内存管理;


常量TRIM_MEMORY_COMPLETE :

-- 全称 :static final int TRIM_MEMORY_COMPLETE = 80;

-- 作用 : 表示 后台进程中的 LRU (最近最少使用) 队列的尾部, 如果需要更多内存, 这些进程将被杀死;


常量TRIM_MEMORY_MODERATE :

-- 全称 :static final int TRIM_MEMORY_MODERATE = 60 ;

-- 作用 : 表示 LRU 进程队列的 中间部分, 释放队列中间及后面进程的内存, 会提高手机性能;


常量用法 : 其中定义了很多类似的常量, 代表一部份进程, 将该常量传入onTrimMemory(int level) 可以杀死指定集合的进程;



4. Application 类分析



(1)ComponentCallbacks 集合列表


列表定义 :

-- 定义方式 :private ArrayList<ComponentCallbacks> mComponentCallbacks =new ArrayList<ComponentCallbacks>();

-- 使用位置 : 在onConfigurationChanged(),onLowMemory(),onTrimMemory() 方法中使用了 该列表;

-- 执行内容 : ComponentCallbacks 子类 即组件, 都实现了上面的三种方法, 在 Application 中的对应方法中分别遍历组件调用组件本身的对应方法;


注册 和 删除组件 : 每创建一个组件都将这个组件注册, 组件销毁时 从列表中删除组件;

    public void registerComponentCallbacks(ComponentCallbacks callback) {        synchronized (mComponentCallbacks) {            mComponentCallbacks.add(callback);        }    }    public void unregisterComponentCallbacks(ComponentCallbacks callback) {        synchronized (mComponentCallbacks) {            mComponentCallbacks.remove(callback);        }    }


(2)ActivityLifecycleCallbacks 接口介绍


ActivityLifecycleCallbacks 接口介绍 :

-- 接口作用 : 该接口提供了一套监测 Activity 声明周期的回调方法;

-- 注册 Activity 声明周期监听方法 :

    public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {        synchronized (mActivityLifecycleCallbacks) {            mActivityLifecycleCallbacks.add(callback);        }    }
-- 取消监听方法 :

    public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {        synchronized (mActivityLifecycleCallbacks) {            mActivityLifecycleCallbacks.remove(callback);        }    }
-- 接口代码 :
    public interface ActivityLifecycleCallbacks {        void onActivityCreated(Activity activity, Bundle savedInstanceState);        void onActivityStarted(Activity activity);        void onActivityResumed(Activity activity);        void onActivityPaused(Activity activity);        void onActivityStopped(Activity activity);        void onActivitySaveInstanceState(Activity activity, Bundle outState);        void onActivityDestroyed(Activity activity);    }




三. Application 相关示例



1. 自定义 Application 基本使用



(1) 创建 自定义 Application


创建 Application : 创建一个类, 继承android.app.Application 类, 实现最基本的 onCreate() 方法即可;

-- 示例 :

package cn.org.octopus.application;import android.app.Application;public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();}}


(2) 注册 Application


在 Manifest.xml 中注册 Application : 在 <application> 标签中添加 android:name 属性, 属性值就是 自定义 MyApplication 路径;

-- 示例 :

    <application android:name="cn.org.octopus.application.MyApplication" >


2. 保存崩溃日志到文件



(1)UncaughtExceptionHandler 简介


UncaughtExceptionHandler 未捕获异常处理类简介 :

-- 线程相关 : 每个线程都有一个未捕获异常处理类;


使用自定义UncaughtExceptionHandler 类代替 线程默认的UncaughtExceptionHandler 类 :

/* * Android 中每个线程都有其指定的 未捕获异常处理类 UncaughtExceptionHandler * 这里我们将该线程的异常处理类获取, 将其赋予本类中的成员变量, 将本类设置为线程默认的 未捕获异常处理类 * 这样就相当与在 UncaughtExceptionHandler 的外层包装了一层, 我们可以对未捕获的异常信息进行任何操作 *///获取系统默认的UncaughtException处理器mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();//设置该CrashHandler为程序的默认处理器Thread.setDefaultUncaughtExceptionHandler(this);


函数驱动动力 :

-- 回调方法 : 当出现了未捕获异常时, 在崩溃前会回调uncaughtException() 方法, 该方法驱动其它方法运行;

-- 详细方法 :public void uncaughtException(Thread thread, Throwable ex);

-- 重写方法 : 在方法中使用 用户自行处理 Throwable ex 抛出的异常, 如果用户没有处理, 使用默认的异常处理器;

if (!handleException(ex) && mDefaultHandler != null) {//如果用户没有处理则让系统默认的异常处理器来处理mDefaultHandler.uncaughtException(thread, ex);} 



(2) 收集相关参数信息


获取设备信息, 异常信息 :Field[] fields = Build.class.getDeclaredFields();

-- 将获取的信息转为字符串 :

/* * 该字段封装了很多信息 * 包括 : 设备信息 异常信息等 */Field[] fields = Build.class.getDeclaredFields();for (Field field : fields) {try {field.setAccessible(true);infos.put(field.getName(), field.get(null).toString());Log.d(TAG, field.getName() + " : " + field.get(null));} catch (Exception e) {Log.e(TAG, "an error occured when collect crash info", e);}}


(3) 在 Application 中注册该类


Application 中注册 : 具体内容请详看代码;

//注册异常日志处理类CrashHandler crashHandler = CrashHandler.getInstance();//初始化异常日志处理类crashHandler.init(getApplicationContext());



3. 监听 Activity 生命周期


(1) 自定义ActivityLifecycleCallbacks 接口实现类


自定义ActivityLifecycleCallbacks类 :

/** * Activity 生命周期监听 * @author octopus * */class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks{@Overridepublic void onActivityCreated(Activity activity,Bundle savedInstanceState) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityCreated");}@Overridepublic void onActivityStarted(Activity activity) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityStarted");}@Overridepublic void onActivityResumed(Activity activity) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityResumed");}@Overridepublic void onActivityPaused(Activity activity) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityPaused");}@Overridepublic void onActivityStopped(Activity activity) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityStopped");}@Overridepublic void onActivitySaveInstanceState(Activity activity,Bundle outState) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivitySaveInstanceState");}@Overridepublic void onActivityDestroyed(Activity activity) {Log.i(TAG_ACTIVITY_LIFE, activity.getClass().getName() + " : onActivityDestroyed");}}


在 onCreate() 方法中注册该类 :

//注册 Activity 声明周期监听器registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());



(2) 执行效果


执行效果 :

[email protected]:~$ adb logcat | grep cn.org.octopus.application.activity.lifeI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityCreatedI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityStartedI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityResumedI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityPausedI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityStoppedI/cn.org.octopus.application.activity.life(12217): cn.org.octopus.application.MainActivity : onActivityDestroyed



博客地址
:http://blog.csdn.net/shulianghan/article/details/40737419

代码下载:Android 应用 Application 经典用法;

--Github:https://github.com/han1202012/ApplicationDemo

--CSDN:http://download.csdn.net/detail/han1202012/8127247

更多相关文章

  1. 最新Android 7.1.1 截屏方法
  2. Android应用程序四种数据存取方法总结
  3. android 加载图片轻松避免OOM(out of memory) 支持设置缓存大小,
  4. android 设置 TextEdit 组件滚动条自动滚动且在末尾追加内容
  5. traceview的使用方法
  6. android Bimtap 各种图片处理方法、图片特效
  7. android 9.0获取mac地址的方法
  8. Android实现音量调节的方法
  9. android常用intent的方法

随机推荐

  1. 社区讨论:Android的架构设计
  2. android与linux内核对比--《Android系统
  3. Android(安卓)Develop
  4. 基于 Android(安卓)NDK 的学习之旅-----J
  5. Android(安卓)如何进行js交互
  6. Android多分辨率适配实践【1】使用字体图
  7. Android中创建对话框(确定取消对话框、单
  8. 全家桶!阿里P8大佬熬夜15天,把所有Android
  9. Tensorflow在手机端的部署——官网Androi
  10. 【Android(安卓)FFMPEG 开发】Android(安