本文出处:
炎之铠csdn博客:http://blog.csdn.net/totond
炎之铠邮箱:yanzhikai_yjk@qq.com
本文原创,转载请注明本出处!
前言
最近的开发中经常使用到Application类,它的用处很多,但是网上的资料有很多是旧的或者是介绍不全的,在这里全面总结一下,先介绍Application的所有方法,再介绍它的使用经验。
本文基于Android6.0源码,API LEVEL 23。
介绍
首先看看官网的介绍:
下面是我对Application类的理解:
- 每个APP都有一个Application实例:如果我们没有继承Application子类自定义它的话,APP会创建一个默认的实例。
- Application实例拥有着与APP一样长的生命周期:在APP开启的时候首先就会实例化它,然后才是入口的Activity或者Service等。
- Application与APP“同生共死”,在一个APP的生命周期只实例化一次,所以它“天生”就是一个单例,不需要使用单例模式去实现它。
- 而上面的官方Note里面说到,通常是没有必要实现Application的子类的,要用单例的话可以自己使用静态单例类实现,要用它的Context的话用
Context.getApplicationContext()
就行了。然而,Application类的作用可不单单是实现一个全局的单例,还有其他的很多功能,下面一一介绍。
Application类功能
Application类的方法
首先看看类结构:
Application是继承自ContextWarpper的,继承来的方法就不在这里说了,下面来看看Application的方法:
onCreate()方法
在Application创建的时候调用,一般用于初始化一些东西,如全局的对象,环境的配置等。
onConfigurationChanged(Configuration newConfig)方法
重写此方法可以监听APP一些配置信息的改变事件(如屏幕旋转等),当配置信息改变的时候会调用这个方法。在Manifest文件下的Activity标签(注意是Activity)里配置android:configChanges
属性相应的配置属性,会使Activity在配置改变时候不会重启,只会执行onConfigurationChanged()方法。如:android:cOnfigChanges="keyboardHidden|orientation|screenSize"
属性可以使Activity旋转时不重启。
onLowMemory()方法
重写此方法可以监听Android系统整体内存较低时候的事件。按我的理解就是,当APP处于前台时,但是所有后台程序都被kill光了,但是还是内存不足时,系统就会调用这个方法告诉APP,兄弟轮到你了。我们可以在这个方法里面释放一些不重要的资源,来保证到时候内存足够而让APP进程不被系统杀掉,或者提醒用户清一下垃圾,让内存清一点空位出来,我的手机老是这样提示我,不知道是不是这个方法惹的祸。
onTrimMemory(int level)方法
这个方法是一个比较难理解的方法,Trim意思是修剪,按我的理解,用这个方法打个比方:
从前有个伟大的妈妈叫Android系统,她有一群子女叫APP,她含辛茹苦地养着这群熊孩子。当系统老妈发现她的工资(内存)不够下个月的开销的时候,就会回调这个方法,告诉她的APP子女,我现在工资不够了,你们赶紧少吃少用点,不然我就要根据你们的重要性高低来一个一个地“清理门户”了。
这里有传入一个int类型的参数level,它告诉APP们内存不足的严重性(越高越严重)。假如这时候系统内存不足,运行着前台和后台一共几个APP,这些不同的APP会收到系统老妈不同的“劝告信息”:
onTerminate()方法
这个方法在程序结束的时候会调用。但是这个方法只用于Android仿真机测试的时候,在Android产品机是不会调用的。所以这个方法并没什么用。
registerActivityLifecycleCallbacks()和unregisterActivityLifecycleCallbacks()
这两个方法用于注册或者注销对APP内所有Activity的生命周期监听,当APP内Activity的生命周期发生变化的时候就会调用ActivityLifecycleCallbacks里面的方法:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.d(TAG,"onActivityCreated: " + activity.getLocalClassName());
}
@Override
public void onActivityStarted(Activity activity) {
Log.d(TAG,"onActivityStarted: " + activity.getLocalClassName());
}
@Override
public void onActivityResumed(Activity activity) {
Log.d(TAG,"onActivityResumed: " + activity.getLocalClassName());
}
@Override
public void onActivityPaused(Activity activity) {
Log.d(TAG,"onActivityPaused: " + activity.getLocalClassName());
}
@Override
public void onActivityStopped(Activity activity) {
Log.d(TAG, "onActivityStopped: " + activity.getLocalClassName());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.d(TAG,"onActivityDestroyed: " + activity.getLocalClassName());
}
});
我们来测试一下,把APP切到后台再打开,log结果是:
onActivityPaused: MainActivity
onActivityStopped: MainActivity
onActivityStarted: MainActivity
onActivityResumed: MainActivity
registerComponentCallbacks()和unregisterComponentCallbacks()方法
用于注册和注销ComponentCallbacks2回调接口,里面的方法前面已经介绍过,看名字就知道:
registerComponentCallbacks(new ComponentCallbacks2() {
@Override
public void onTrimMemory(int level) {
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
}
@Override
public void onLowMemory() {
}
});
Context类也有这两个方法,但是Context类的方法只可以使用ComponentCallbacks,比Application少了一个onTrimMemory()回调。
registerOnProvideAssistDataListener()和unregisterOnProvideAssistDataListener()方法
API18以上的方法,网上关于这两个方法的介绍很少,几乎没有,在官网上的介绍是这样的:
This is called when the user is requesting an assist, to build a full ACTION_ASSIST Intent with all of the context of the current application.
好像是当用户请求帮助的时候会调用这个方法,然后会启动一个ACTION_ASSIST的Intent。什么时候才是用户请求帮助呢?StackOverflow里有的人说是长按Home键,外国的机子会跳出Google Now这个助手,至于国内的机子,我用我自己的华为荣耀6P长按Home键是弹出语音助手,但是没有回调这个方法。然后尝试了一下用下面的代码来发送一个ACTION_ASSIST来看看有什么效果:
Intent intent = new Intent(ACTION_ASSIST);
context.startActivity(intent);
结果打开了我手机上UC浏览器的语音搜索功能。。。
最后还是搞不懂这个方法什么时候会回调,如果有知道的请告知,谢谢!
Application类的使用
要使用自定义的Application,首先就是要自己新建一个Application的子类,然后把它的名字写在manifest文件里面的application标签里的android:name属性就行,如我的Application子类名字是BaseApplication,则:
android:name=".BaseApplication"
1.初始化资源
由于Application类是在APP启动的时候就启动,启动在所有Activity之前,所以可以使用它做资源的初始化操作,如图片资源初始化,WebView的预加载,推送服务的注册等等,注意不要执行耗时操作,会拖慢APP启动速度。
2.数据全局共享
- 可以设置一些全局的共享常量,如一些TAG,枚举值等。
- 可以设置一些全局使用的共享变量数据,如一个全局的Handler等等,但是要注意,这里缓存的变量数据的作用周期只在APP的生命周期,如果APP因为内存不足而结束的话,再开启这些数据就会消失,所以这里只能存储一些不重要的数据来使数据全APP共享,想要储存重要数据的话需要SharePreference、数据库或者文件存储等这些本地存储。
- 可以设置一些静态方法来让其他类调用,来使用Application里面的全局变量,如实现APP一键退出功能时候会用到。
后话
以上就是我对Android中Application的总结和使用经验,基于Android6.0的API,所有的方法都是经过实测的,如有错漏,敬请指正,谢谢!
参考文章
https://developer.android.com/reference/android/app/Application.html
http://blog.csdn.net/man_embedded/article/details/52625619
http://androidperformance.com/2015/07/20/Android-Performance-Memory-onTrimMemory.html
http://blog.csdn.net/android_jianbo/article/details/46228003