相关类
与Activity相关的类有很多,彼此之间通过一些变量都可相互引用
。
如下:
从上图可以看出,每个Activity实例中都含有一个DecorView对象,ViewRootImpl对象,以及WindowManager.LayoutParams对象()——它是DecorView对应的LayoutParams,三者之间的关联由WMG维护(由于WMI完全委托给了WMG)。
attach()
除构造函数,该方法是Activity中第一个被执行的方法。该方法内部会初始化一些Activity中的成员变量。如下:
attachBaseContext(context);//会赋值到mBase成员变量。
mWindow = new PhoneWindow(this);
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();//这里返回的是一个WindowManagerImpl对象
第一个方法会将传入的context保存到mBase成员变量中。
从最后两步可以看出,Activity与它所关联的Window对象中的mWindowManager都是指向同一个WindowManageImpl对象。
startActivity()
所有的startActivity()最终会走到ActivityThread#handleLaunchActivity()。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//略
Activity a = performLaunchActivity(r, customIntent);
//创建Activity实例,并调用到attach(),onCreate(),onStart(),onRestoreInstanceState(),onPostCreate()
if (a != null) {
//略
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
//略
} else {
//略
}
}
performLaunchActivity。其主体代码如下:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//上面是获取待启动activity的信息,并组装成一个ComponentName对象。
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//略
} catch (Exception e) {
//略
}
//在newActivity中,是通过反射拿到一个activity的实例对象的,这里就创建了新的activity对象。
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//makeApplication 反射拿application对象,如果已经存储就直接返回。并调用Application#onCreate()方法。
//略
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
//略
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
//略
if (r.isPersistable()) {//调用到onCreate(),只不过前者调用的是onCreate(Bundle,PersistableBundle),后者调用的是onCreate(Bundle)
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//略
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();//调用Activity#onStart()
r.stopped = false;
}
if (!r.activity.mFinished) {//调用onRestoreInstanceState()
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
//由上述两个的判断顺序可以知道,onRestoreInstanceState()是在onStart()之后调用的,并且在有Bundle对象的时候才调用
if (!r.activity.mFinished) {//调用Activity#onPostCreate()
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
//略
}
}
r.paused = true;
mActivities.put(r.token, r);
} //略
return activity;
}
在上述过程中通过createBaseContextForActivity()创建了一个Context对象,方法如下:
而在第四行,将activity传递到了ContextImpl#mOuterContext属性中。因此,在Activity可以通过mBase访问到ContextImpl对象,在ContextImpl中可以通过mOuterContext访问到它关联的Activity对象。
从这里也可以看到,一个activity就有一个Context。
经performLaunchActivity()执行完毕之后,得到了一个Activity实例,并调用了attach()->onCreate()->onStart()->onRestoreInstanceState()->onPostCreate()。但并没有调用onResume()。
再回到handleLaunchActivity()中,调用完performLaunchActivity()之后,会调用handleResumeActivity()。如下:
performResumeActivity()执行完毕之后,获取了新建Activity的Window对象(在Activity#attach()中创建)以及DecorView(Activity#onCreate()中调用了setContentView()方法时创建),并将DecorView对象添加到Window中。
通过WindowManager#addView()内部的一系列执行,最终会对View进行测量、布局和显示。这样整个界面就显示出来了。
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);//这里调用将传入的Activity保存到mOuterContext变量中。
Context baseContext = appContext;
//略
return baseContext;
}
我们可以发现在整个过程中,baseContext都是ContextImpl类型的。而该对象会传递到Activity#attach()中,并且最终被赋值到ContextWrapper#mBase(Activity也是间接继承于ContextWrapper)属性。而在第四行,将activity传递到了ContextImpl#mOuterContext属性中。因此,在Activity可以通过mBase访问到ContextImpl对象,在ContextImpl中可以通过mOuterContext访问到它关联的Activity对象。
从这里也可以看到,一个activity就有一个Context。
经performLaunchActivity()执行完毕之后,得到了一个Activity实例,并调用了attach()->onCreate()->onStart()->onRestoreInstanceState()->onPostCreate()。但并没有调用onResume()。
再回到handleLaunchActivity()中,调用完performLaunchActivity()之后,会调用handleResumeActivity()。如下:
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
//略
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
//略
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
//略
}
该方法中会调用performResumeActivity(),这里又会调用Activity#performResume(),最终会在这里通过Instrumentation调用onResume()。performResumeActivity()执行完毕之后,获取了新建Activity的Window对象(在Activity#attach()中创建)以及DecorView(Activity#onCreate()中调用了setContentView()方法时创建),并将DecorView对象添加到Window中。
通过WindowManager#addView()内部的一系列执行,最终会对View进行测量、布局和显示。这样整个界面就显示出来了。
整个过程:
Activity#startActivity()->ActivityThread#handleLaunchActivity()->ActivityThread#performLaunchActivity()->Activity#attach()->Activity#onCreate()到Activity#onPostCreate()的生命周期->ActivityThread#handleResumeActivity()->ActivityThread#performResumeActivity()->Activity#onResume()->WindowManagerImpl#addView()->ViewRootImpl#setView()->ViewRootImpl#requestLayout()->ViewRootImpl#performTraversals()->ViewRootImpl#performMeasure()->ViewRootImpl#performLayout()->ViewRootImpl#performDraw()->Session#addToDisplay()->WindowManagerService#addWindow()到这一步,整个界面才展示出来。
Activity的创建是在ActivityThread#performLaunchActivity()中完成的。
与Activity关联的PhoneWindow对象是在Activity#onCreate()中调用setContentView()时完成的,同时也完成了整个xml文件的解析与构建——View树构建完毕,但未measure,layout与draw。
ViewRootImpl#performMeasure(),performLayout,performDraw():执行view的measure,layout与draw的过程。
WMS#addWindow()显示整个Window,才显示出具体的布局。