博客地址: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 相关代码:

[java] view plain copy
  1. /**
  2. *Calledwhentheapplicationisstarting,beforeanyotherapplication
  3. *objectshavebeencreated.Implementationsshouldbeasquickas
  4. *possible(forexampleusinglazyinitializationofstate)sincethetime
  5. *spentinthisfunctiondirectlyimpactstheperformanceofstartingthe
  6. *firstactivity,service,orreceiverinaprocess.
  7. *Ifyouoverridethismethod,besuretocallsuper.onCreate().
  8. */
  9. publicvoidonCreate(){
  10. }
  11. /**
  12. *Thismethodisforuseinemulatedprocessenvironments.Itwill
  13. *neverbecalledonaproductionAndroiddevice,whereprocessesare
  14. *removedbysimplykillingthem;nousercode(includingthiscallback)
  15. *isexecutedwhendoingso.
  16. */
  17. publicvoidonTerminate(){
  18. }
  19. publicvoidonConfigurationChanged(ConfigurationnewConfig){
  20. Object[]callbacks=collectComponentCallbacks();
  21. if(callbacks!=null){
  22. for(inti=0;i<callbacks.length;i++){
  23. ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
  24. }
  25. }
  26. }
  27. publicvoidonLowMemory(){
  28. Object[]callbacks=collectComponentCallbacks();
  29. if(callbacks!=null){
  30. for(inti=0;i<callbacks.length;i++){
  31. ((ComponentCallbacks)callbacks[i]).onLowMemory();
  32. }
  33. }
  34. }





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 示例:

[java] view plain copy
  1. packagecn.org.octopus.application;
  2. importjava.util.HashMap;
  3. importjava.util.Map;
  4. importandroid.app.Application;
  5. publicclassMyApplicationextendsApplication{
  6. /**用于数据传递的Map集合*/
  7. privateMap<String,Object>transferMap;
  8. /**用于缓存数据的Map集合*/
  9. privateMap<String,Object>cacheMap;
  10. @Override
  11. publicvoidonCreate(){
  12. super.onCreate();
  13. //初始化用于数据传递的Map集合
  14. transferMap=newHashMap<String,Object>();
  15. //初始化用于数据缓存的Map集合
  16. cacheMap=newHashMap<String,Object>();
  17. }
  18. /**
  19. *获取数据传递Map集合
  20. *@return
  21. *数据传递Map集合
  22. */
  23. publicMap<String,Object>getTransferMap(){
  24. returntransferMap;
  25. }
  26. /**
  27. *获取数据缓存Map集合
  28. *@return
  29. *数据缓存Map集合
  30. */
  31. publicMap<String,Object>getCacheMap(){
  32. returncacheMap;
  33. }
  34. }


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 使用分析_第1张图片



(2) 相关类介绍


Application 相关类介绍:

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

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

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

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

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



2. CompnentCallbacks 接口


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

[java] view plain copy
  1. packageandroid.content;
  2. importandroid.content.res.Configuration;
  3. publicinterfaceComponentCallbacks{
  4. voidonConfigurationChanged(ConfigurationnewConfig);
  5. voidonLowMemory();
  6. }



(1)onConfigurationChanged() 方法介绍


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

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

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

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

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

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



(2)onLowMemory() 方法介绍


方法介绍:

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

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

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

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

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



3. ComponentCallbacks2 接口


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

[java] view plain copy
  1. packageandroid.content;
  2. publicinterfaceComponentCallbacks2extendsComponentCallbacks{
  3. staticfinalintTRIM_MEMORY_COMPLETE=80;
  4. staticfinalintTRIM_MEMORY_MODERATE=60;
  5. ......
  6. voidonTrimMemory(intlevel);
  7. }


(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 中的对应方法中分别遍历组件调用组件本身的对应方法;


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

[java] view plain copy
  1. publicvoidregisterComponentCallbacks(ComponentCallbackscallback){
  2. synchronized(mComponentCallbacks){
  3. mComponentCallbacks.add(callback);
  4. }
  5. }
  6. publicvoidunregisterComponentCallbacks(ComponentCallbackscallback){
  7. synchronized(mComponentCallbacks){
  8. mComponentCallbacks.remove(callback);
  9. }
  10. }


(2)ActivityLifecycleCallbacks 接口介绍


ActivityLifecycleCallbacks 接口介绍:

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

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

[java] view plain copy
  1. publicvoidregisterActivityLifecycleCallbacks(ActivityLifecycleCallbackscallback){
  2. synchronized(mActivityLifecycleCallbacks){
  3. mActivityLifecycleCallbacks.add(callback);
  4. }
  5. }
-- 取消监听方法 :

[java] view plain copy
  1. publicvoidunregisterActivityLifecycleCallbacks(ActivityLifecycleCallbackscallback){
  2. synchronized(mActivityLifecycleCallbacks){
  3. mActivityLifecycleCallbacks.remove(callback);
  4. }
  5. }
-- 接口代码 :
[java] view plain copy
  1. publicinterfaceActivityLifecycleCallbacks{
  2. voidonActivityCreated(Activityactivity,BundlesavedInstanceState);
  3. voidonActivityStarted(Activityactivity);
  4. voidonActivityResumed(Activityactivity);
  5. voidonActivityPaused(Activityactivity);
  6. voidonActivityStopped(Activityactivity);
  7. voidonActivitySaveInstanceState(Activityactivity,BundleoutState);
  8. voidonActivityDestroyed(Activityactivity);
  9. }




三. Application 相关示例



1. 自定义 Application 基本使用



(1) 创建 自定义 Application


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

--示例:

[java] view plain copy
  1. packagecn.org.octopus.application;
  2. importandroid.app.Application;
  3. publicclassMyApplicationextendsApplication{
  4. @Override
  5. publicvoidonCreate(){
  6. super.onCreate();
  7. }
  8. }


(2) 注册 Application


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

--示例:

[java] view plain copy
  1. <applicationandroid:name="cn.org.octopus.application.MyApplication">


2. 保存崩溃日志到文件



(1)UncaughtExceptionHandler 简介


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

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


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

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


函数驱动动力:

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

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

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

[java] view plain copy
  1. if(!handleException(ex)&&mDefaultHandler!=null){
  2. //如果用户没有处理则让系统默认的异常处理器来处理
  3. mDefaultHandler.uncaughtException(thread,ex);
  4. }



(2) 收集相关参数信息


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

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

[java] view plain copy
  1. /*
  2. *该字段封装了很多信息
  3. *包括:设备信息异常信息等
  4. */
  5. Field[]fields=Build.class.getDeclaredFields();
  6. for(Fieldfield:fields){
  7. try{
  8. field.setAccessible(true);
  9. infos.put(field.getName(),field.get(null).toString());
  10. Log.d(TAG,field.getName()+":"+field.get(null));
  11. }catch(Exceptione){
  12. Log.e(TAG,"anerroroccuredwhencollectcrashinfo",e);
  13. }
  14. }


(3) 在 Application 中注册该类


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

[java] view plain copy
  1. //注册异常日志处理类
  2. CrashHandlercrashHandler=CrashHandler.getInstance();
  3. //初始化异常日志处理类
  4. crashHandler.init(getApplicationContext());



3. 监听 Activity 生命周期


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


自定义ActivityLifecycleCallbacks类:

[java] view plain copy
  1. /**
  2. *Activity生命周期监听
  3. *@authoroctopus
  4. *
  5. */
  6. classMyActivityLifecycleCallbacksimplementsActivityLifecycleCallbacks{
  7. @Override
  8. publicvoidonActivityCreated(Activityactivity,
  9. BundlesavedInstanceState){
  10. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityCreated");
  11. }
  12. @Override
  13. publicvoidonActivityStarted(Activityactivity){
  14. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityStarted");
  15. }
  16. @Override
  17. publicvoidonActivityResumed(Activityactivity){
  18. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityResumed");
  19. }
  20. @Override
  21. publicvoidonActivityPaused(Activityactivity){
  22. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityPaused");
  23. }
  24. @Override
  25. publicvoidonActivityStopped(Activityactivity){
  26. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityStopped");
  27. }
  28. @Override
  29. publicvoidonActivitySaveInstanceState(Activityactivity,
  30. BundleoutState){
  31. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivitySaveInstanceState");
  32. }
  33. @Override
  34. publicvoidonActivityDestroyed(Activityactivity){
  35. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityDestroyed");
  36. }
  37. }


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

[java] view plain copy
  1. //注册Activity声明周期监听器
  2. registerActivityLifecycleCallbacks(newMyActivityLifecycleCallbacks());



(2) 执行效果


执行效果:

[plain] view plain copy
  1. [email protected]:~$adblogcat|grepcn.org.octopus.application.activity.life
  2. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityCreated
  3. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityStarted
  4. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityResumed
  5. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityPaused
  6. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityStopped
  7. I/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

博客地址: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 相关代码:

[java] view plain copy
  1. /**
  2. *Calledwhentheapplicationisstarting,beforeanyotherapplication
  3. *objectshavebeencreated.Implementationsshouldbeasquickas
  4. *possible(forexampleusinglazyinitializationofstate)sincethetime
  5. *spentinthisfunctiondirectlyimpactstheperformanceofstartingthe
  6. *firstactivity,service,orreceiverinaprocess.
  7. *Ifyouoverridethismethod,besuretocallsuper.onCreate().
  8. */
  9. publicvoidonCreate(){
  10. }
  11. /**
  12. *Thismethodisforuseinemulatedprocessenvironments.Itwill
  13. *neverbecalledonaproductionAndroiddevice,whereprocessesare
  14. *removedbysimplykillingthem;nousercode(includingthiscallback)
  15. *isexecutedwhendoingso.
  16. */
  17. publicvoidonTerminate(){
  18. }
  19. publicvoidonConfigurationChanged(ConfigurationnewConfig){
  20. Object[]callbacks=collectComponentCallbacks();
  21. if(callbacks!=null){
  22. for(inti=0;i<callbacks.length;i++){
  23. ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
  24. }
  25. }
  26. }
  27. publicvoidonLowMemory(){
  28. Object[]callbacks=collectComponentCallbacks();
  29. if(callbacks!=null){
  30. for(inti=0;i<callbacks.length;i++){
  31. ((ComponentCallbacks)callbacks[i]).onLowMemory();
  32. }
  33. }
  34. }





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 示例:

[java] view plain copy
  1. packagecn.org.octopus.application;
  2. importjava.util.HashMap;
  3. importjava.util.Map;
  4. importandroid.app.Application;
  5. publicclassMyApplicationextendsApplication{
  6. /**用于数据传递的Map集合*/
  7. privateMap<String,Object>transferMap;
  8. /**用于缓存数据的Map集合*/
  9. privateMap<String,Object>cacheMap;
  10. @Override
  11. publicvoidonCreate(){
  12. super.onCreate();
  13. //初始化用于数据传递的Map集合
  14. transferMap=newHashMap<String,Object>();
  15. //初始化用于数据缓存的Map集合
  16. cacheMap=newHashMap<String,Object>();
  17. }
  18. /**
  19. *获取数据传递Map集合
  20. *@return
  21. *数据传递Map集合
  22. */
  23. publicMap<String,Object>getTransferMap(){
  24. returntransferMap;
  25. }
  26. /**
  27. *获取数据缓存Map集合
  28. *@return
  29. *数据缓存Map集合
  30. */
  31. publicMap<String,Object>getCacheMap(){
  32. returncacheMap;
  33. }
  34. }


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张图片



(2) 相关类介绍


Application 相关类介绍:

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

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

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

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

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



2. CompnentCallbacks 接口


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

[java] view plain copy
  1. packageandroid.content;
  2. importandroid.content.res.Configuration;
  3. publicinterfaceComponentCallbacks{
  4. voidonConfigurationChanged(ConfigurationnewConfig);
  5. voidonLowMemory();
  6. }



(1)onConfigurationChanged() 方法介绍


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

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

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

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

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

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



(2)onLowMemory() 方法介绍


方法介绍:

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

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

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

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

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



3. ComponentCallbacks2 接口


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

[java] view plain copy
  1. packageandroid.content;
  2. publicinterfaceComponentCallbacks2extendsComponentCallbacks{
  3. staticfinalintTRIM_MEMORY_COMPLETE=80;
  4. staticfinalintTRIM_MEMORY_MODERATE=60;
  5. ......
  6. voidonTrimMemory(intlevel);
  7. }


(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 中的对应方法中分别遍历组件调用组件本身的对应方法;


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

[java] view plain copy
  1. publicvoidregisterComponentCallbacks(ComponentCallbackscallback){
  2. synchronized(mComponentCallbacks){
  3. mComponentCallbacks.add(callback);
  4. }
  5. }
  6. publicvoidunregisterComponentCallbacks(ComponentCallbackscallback){
  7. synchronized(mComponentCallbacks){
  8. mComponentCallbacks.remove(callback);
  9. }
  10. }


(2)ActivityLifecycleCallbacks 接口介绍


ActivityLifecycleCallbacks 接口介绍:

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

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

[java] view plain copy
  1. publicvoidregisterActivityLifecycleCallbacks(ActivityLifecycleCallbackscallback){
  2. synchronized(mActivityLifecycleCallbacks){
  3. mActivityLifecycleCallbacks.add(callback);
  4. }
  5. }
-- 取消监听方法 :

[java] view plain copy
  1. publicvoidunregisterActivityLifecycleCallbacks(ActivityLifecycleCallbackscallback){
  2. synchronized(mActivityLifecycleCallbacks){
  3. mActivityLifecycleCallbacks.remove(callback);
  4. }
  5. }
-- 接口代码 :
[java] view plain copy
  1. publicinterfaceActivityLifecycleCallbacks{
  2. voidonActivityCreated(Activityactivity,BundlesavedInstanceState);
  3. voidonActivityStarted(Activityactivity);
  4. voidonActivityResumed(Activityactivity);
  5. voidonActivityPaused(Activityactivity);
  6. voidonActivityStopped(Activityactivity);
  7. voidonActivitySaveInstanceState(Activityactivity,BundleoutState);
  8. voidonActivityDestroyed(Activityactivity);
  9. }




三. Application 相关示例



1. 自定义 Application 基本使用



(1) 创建 自定义 Application


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

--示例:

[java] view plain copy
  1. packagecn.org.octopus.application;
  2. importandroid.app.Application;
  3. publicclassMyApplicationextendsApplication{
  4. @Override
  5. publicvoidonCreate(){
  6. super.onCreate();
  7. }
  8. }


(2) 注册 Application


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

--示例:

[java] view plain copy
  1. <applicationandroid:name="cn.org.octopus.application.MyApplication">


2. 保存崩溃日志到文件



(1)UncaughtExceptionHandler 简介


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

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


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

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


函数驱动动力:

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

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

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

[java] view plain copy
  1. if(!handleException(ex)&&mDefaultHandler!=null){
  2. //如果用户没有处理则让系统默认的异常处理器来处理
  3. mDefaultHandler.uncaughtException(thread,ex);
  4. }



(2) 收集相关参数信息


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

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

[java] view plain copy
  1. /*
  2. *该字段封装了很多信息
  3. *包括:设备信息异常信息等
  4. */
  5. Field[]fields=Build.class.getDeclaredFields();
  6. for(Fieldfield:fields){
  7. try{
  8. field.setAccessible(true);
  9. infos.put(field.getName(),field.get(null).toString());
  10. Log.d(TAG,field.getName()+":"+field.get(null));
  11. }catch(Exceptione){
  12. Log.e(TAG,"anerroroccuredwhencollectcrashinfo",e);
  13. }
  14. }


(3) 在 Application 中注册该类


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

[java] view plain copy
  1. //注册异常日志处理类
  2. CrashHandlercrashHandler=CrashHandler.getInstance();
  3. //初始化异常日志处理类
  4. crashHandler.init(getApplicationContext());



3. 监听 Activity 生命周期


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


自定义ActivityLifecycleCallbacks类:

[java] view plain copy
  1. /**
  2. *Activity生命周期监听
  3. *@authoroctopus
  4. *
  5. */
  6. classMyActivityLifecycleCallbacksimplementsActivityLifecycleCallbacks{
  7. @Override
  8. publicvoidonActivityCreated(Activityactivity,
  9. BundlesavedInstanceState){
  10. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityCreated");
  11. }
  12. @Override
  13. publicvoidonActivityStarted(Activityactivity){
  14. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityStarted");
  15. }
  16. @Override
  17. publicvoidonActivityResumed(Activityactivity){
  18. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityResumed");
  19. }
  20. @Override
  21. publicvoidonActivityPaused(Activityactivity){
  22. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityPaused");
  23. }
  24. @Override
  25. publicvoidonActivityStopped(Activityactivity){
  26. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityStopped");
  27. }
  28. @Override
  29. publicvoidonActivitySaveInstanceState(Activityactivity,
  30. BundleoutState){
  31. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivitySaveInstanceState");
  32. }
  33. @Override
  34. publicvoidonActivityDestroyed(Activityactivity){
  35. Log.i(TAG_ACTIVITY_LIFE,activity.getClass().getName()+":onActivityDestroyed");
  36. }
  37. }


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

[java] view plain copy
  1. //注册Activity声明周期监听器
  2. registerActivityLifecycleCallbacks(newMyActivityLifecycleCallbacks());



(2) 执行效果


执行效果:

[plain] view plain copy
  1. [email protected]:~$adblogcat|grepcn.org.octopus.application.activity.life
  2. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityCreated
  3. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityStarted
  4. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityResumed
  5. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityPaused
  6. I/cn.org.octopus.application.activity.life(12217):cn.org.octopus.application.MainActivity:onActivityStopped
  7. I/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添加图片到本地,无法即使刷新的解决方法
  2. Android 常用第三方组件
  3. Android每天定时任务启动方法
  4. android Timer使用方法
  5. Android 实现清除缓存
  6. Android 使用git下载源码报错解决方法
  7. Android中的onCreateOptionsMenu()方法和onOptionsItemSelected()方
  8. 关于androidSDK更新缓慢的解决方法(以W7为例)
  9. 执行Android JUnit测试出现java.net.SocketException: Permissio

随机推荐

  1. Android实现短信验证功能(使用前的准备)
  2. android窗体动画:activity启动从底部向上
  3. Android卸载程序之后跳转到指定的反馈页
  4. Android指纹支付 - android M / P 全适配
  5. 在android开发中应该如何管理内存或者是
  6. Android(安卓)笔记 :Android(安卓)热修复
  7. android使用Fragment实现底部菜单使用sho
  8. Android(安卓)双进程守护
  9. 基于Android(安卓)RIL层实现来电拦截的技
  10. Android保活从入门到放弃:乖乖引导用户加