1、ContextWrapper继承关系:ContextWrapper extends Context,从类名上理解即是对Context类的包装。
源码注释:Proxying implementation of Context that simply delegates(代理或代表) all of its calls to another Context. Can be subclassed to modify behavior without changing the original Context.
说明:在ContextWrapper类中,只有唯一的一属性Context mBase,事实上在ContextWrapper中所有方法都是围绕着mBase做封装,提供一系列供外部使用的get和set等方法,个人认为google这一做法旨在降低调用者使用Context的难度。
2、ComponentCallbacks2继承关系:extends ComponentCallbacks,
源码注释:Extended ComponentCallbacks interface with a new callback for finer-grained memory management.只新增了void onTrimMemory(int level)抽象方法,字面意思是修剪内存,该接口主要是依据不同的级别来回收内存。因此,ComponentCallbacks2接口的作用就是让开发者在适当时机修剪释放内存。
3、ComponentCallbacks:最上层接口,只包含两个抽象方法:(1)void onConfigurationChanged(Configuration newConfig):当组件在运行时配置发生了改变该接口就会回调。(如屏幕方向、锁屏)
(2)void onLowMemory():当系统内存不足时或者程序所在的进程应该释放内存时会回调该方法
二、Application构造方法:
public Application() {
super(null);
}
说明:目前只分析了使用Instrumentation框架时Application的构造过程,流程是大概是这样的:
1、首先在Androidmanifest的<application>声明了android:name=".app.ManifestApplication"属性之后,经过xml解析,获取到Application完整类名;
2、接着由Instrumentation类的newApplication方法通过反射的方式来实例化Application。
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
3、实例化app之后马上就会执行attach方法,注意这个attach方法是个隐藏方法,在这个方法中又会调用父类ContextWrapper的attachBaseContext方法
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
4、执行ContextWrapper的attachBaseContext方法,真正为mBase属性赋值。protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
5、只有执行了app.attach(context)方法之后,Application的实例化工作才算完成,且最关键的一步是为mBase重新赋值。
三、Application的内部接口:在Application中定义了ActivityLifecycleCallbacks和OnProvideAssistDataListener两个接口。
1、ActivityLifecycleCallbacks接口:Activity生命周期方法的回调接口,需要注意的是该回调方法是在Activity类中回调的,且在Activity类的不同的生命周期方法中各自的回调时机是不一样的,有可能是在生命周期方法开始执行或执行结束的时候才回调,但是对于Activity实现类来说,都在super.onXXX()中回调,因此Activity实现类的ActivityLifecycleCallbacks回调时机取决于各自生命周期方法中的super.onXXX()的调用时机,而不一定在生命周期方法的开始或结束时调用。
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);
}
2、OnProvideAssistDataListener接口:该接口是API18的新增接口,主要是用于助手应用与本应用的数据交互接口,使用本接口需要在Application实现类中进行在注册与注销。
public interface OnProvideAssistDataListener {
/**
* This is called when the user is requesting an assist, to build a full
* {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
* application. You can override this method to place into the bundle anything
* you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
* of the assist Intent.
*/
public void onProvideAssistData(Activity activity, Bundle data);
}
四、Application的成员变量:只有四个成员变量,其中三个是Callbacks类型的列表数据。
1、private ArrayList<ComponentCallbacks> mComponentCallbacks = new ArrayList<ComponentCallbacks>(); 所有组件都可能触发该回调接口
2、private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<ActivityLifecycleCallbacks>();只有Activity组件会触发该接口;
3、private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;由助手应用触发该接口;
4、public LoadedApk mLoadedApk:apk加载类,注意该属性是一隐藏属性,只供内部api使用,是从ContextImpl类中获取获取其实例。如下
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
五、Application的方法:主要分为公有方法、包访问方法以及私有方法
1、公有方法:Application的实现类都可以重写这些方法,如onCreate、onTerminate等
(1)其中的三个Callbacks类型的成员变量就对应的各自的registerXXCallbacks和unregisterXXCallbacks两个方法,注意是成对出现,忘记unregisterXXCallbacks有可能出现内存泄漏的风险,比如使用registerActivityLifecycleCallbacks方法,其回调接口是带有activity这一参数的,在activity被执行完生命周期方法时,按理应该是被虚拟机回收的,但是因为这个回调的存在导致不能进行回收,从而出现内存泄漏。(当然还未测试)
(2)onCreate方法:当application启动时,就会去执行,单单看这个类还不知道是由谁去触发该方法,它先于activity、service和receiver的create方法执行,但是不包括ContentProvider,经验证ContentProvider的oncreate方法确实先于application。当子类重写该方法时,google建议应尽可能减少该方法的执行时间,即不要做什么耗时操作,否则会直接影响第一个Activity启动的时间。
(3)onTerminate方法:该方法是在仿真器运行环境下才会被回调的,在android设备上仅仅简单的kill吊进行时该方法并不会被回调,因此不建议在该回调方法
中实现业务相关的代码。
(4)onConfigurationChanged和onLowMemory方法:都是来自ComponentCallbacks接口,当设备的属性如系统字体、屏幕方向改变时,会触发该方法
(5)onTrimMemory方法:来自ComponentCallbacks2接口,google提供的用于回收内存的方法。(将在activity篇中总结)
2、而包访问方法是被同级包内所调用的,起着桥梁的作用,主要是收集来自上层的接口回调信息以及Activity生命周期回调事件的分发方法。
(1)attach方法:前面已经提及,是由Instrumentation类的newApplication方法所调用。
(2)dispatchActivityXX方法:这类方法是由Activity类来调用,需要注意的是Activity类中各个生命周期方法的调用时机是不一样的,但是大多数都是在生命周期方法的末尾或靠近末尾的时候执行调用,从这个层面来讲可以理解为:只要出现回调,那么Activity类(注意不是其子类)中各个生命周期方法已经执行完毕了。
3、私有方法作用就是被类中的其他非私有方法服务,在这类中只有两个方法:collectComponentCallbacks和collectActivityLifecycleCallbacks方法。