Activity啟動(dòng)過(guò)程
(以及Activity ActivityThread Window WindowManager viewRootImpl View 之間的關(guān)系)
ActivityThread是程序的入口,在其main函數(shù)中,
- 初始化looper,并開(kāi)啟loop函數(shù)愧旦,以及new出自身的實(shí)例耍贾,調(diào)用了attach方法,部分代碼如下
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
Looper.loop();
創(chuàng)建新的Activity之前,會(huì)先初始化application(如果不存在)净薛。
在創(chuàng)建Activity的過(guò)程中瘩例,首先調(diào)用
scheduleLaunchActivity()
之后便調(diào)用
handleLaunchActivity()
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
handleConfigurationChanged(null, null);
//初始化 WindowManagerService,主要是獲取到 WindowManagerService 代理對(duì)象
WindowManagerGlobal.initialize();
//初始化Activity
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
//顯示布局
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
}
在performLaunchActivity 方法中赦拘,會(huì)new一個(gè)activity實(shí)例出來(lái)蛮原,并執(zhí)行attach方法
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
......
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, window, r.configCallback);
Activity.attach方法初始化了window,
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
window是一個(gè)抽象類,具體實(shí)現(xiàn)是PhoneWindow另绩,Android中不論是activity還是dialog儒陨,用的都是phoneWindow。同時(shí)得到一個(gè) WindowManager 對(duì)象笋籽,WindowManager 是一個(gè)抽象類蹦漠,這個(gè) WindowManager 的具體實(shí)現(xiàn)是在 WindowManagerImpl 中
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
每個(gè) Activity 會(huì)有一個(gè) WindowManager 對(duì)象,這個(gè) mWindowManager 就是和 WindowManagerService 進(jìn)行通信车海,也是 WindowManagerService 識(shí)別 View 具體屬于那個(gè) Activity 的關(guān)鍵笛园,創(chuàng)建時(shí)傳入 IBinder 類型的 mToken隘击。
在執(zhí)行完這些后,就執(zhí)行完了activity的attach方法研铆,然后回到performLaunchActivity方法中繼續(xù)埋同,
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
這個(gè)方法會(huì)回調(diào)activity的onCreate方法, 通常我們?cè)趏nCreate中設(shè)置contentView,
把布局設(shè)置給activity,其實(shí)這個(gè)時(shí)候只是調(diào)用了window來(lái)給window設(shè)置布局:
Activity.setContentView():
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
PhoneWindow.setContentView():
public void setContentView(int layoutResID) {
...
installDecor();
...
}
installDecor方法初始化DectorView和mContentParent棵红,mContentParent是DecorView的子view凶赁。
這時(shí)只是創(chuàng)建了 PhoneWindow,和DecorView逆甜,但目前二者也沒(méi)有任何關(guān)系虱肄,產(chǎn)生關(guān)系是在ActivityThread.performResumeActivity 中,再調(diào)用 r.activity.performResume()咏窿,調(diào)用 r.activity.makeVisible,將 DecorView 添加到當(dāng)前的 Window 上素征。
至此Activity.onCreate方法執(zhí)行完畢集嵌,ActivityThread的performLaunchActivity和handleLaunchActivity從邏輯上基本執(zhí)行完。
總結(jié)下:初始化了Activity御毅,給Activity初始化了window根欧,WindowManager。為window初始化了DecorView
執(zhí)行完這些之后會(huì)執(zhí)行ActivityThread.handleStartActivity 以及 performStartActivity這兩個(gè)方法亚享,對(duì)應(yīng)的會(huì)執(zhí)行Activity.onStart方法咽块。這幾個(gè)不涉及UI部分,暫不贅述欺税。
緊接著侈沪,就到了handleResumeActivity,
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
//執(zhí)行到 onResume()
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
boolean willBeVisible = !a.mStartedActivity;
...
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);
}
}
...
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
...
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
//添加視圖晚凿,詳見(jiàn)下面分析
r.activity.makeVisible();
}
}
//resume 完成
if (reallyResume) {
ActivityManagerNative.getDefault().activityResumed(token);
}
} else {
...
}
}
Activity.makeVisible():
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
在此方法中會(huì)調(diào)用performResumeActivity,performResumeActivity中回調(diào)Activity.onResume亭罪。
在這這些方法中,首先會(huì)吧Activity的dector指向window的DectorView歼秽,
然后通過(guò)WindowManager添加应役。WindowManager 的 addView 的具體實(shí)現(xiàn)在 WindowManagerImpl 中,而 WindowManagerImpl 的 addView 又會(huì)調(diào)用 WindowManagerGlobal.addView()燥筷。
WindowManagerGlobal.addView():
public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {
...
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);
...
}
這個(gè)過(guò)程創(chuàng)建一個(gè) ViewRootImpl箩祥,并將之前創(chuàng)建的 DecoView 作為參數(shù)傳入,以后 DecoView 的事件都由 ViewRootImpl 來(lái)管理了肆氓,比如袍祖,DecoView 上添加 View,刪除 View谢揪。
ViewRootImpl 實(shí)現(xiàn)了 ViewParent 這個(gè)接口蕉陋。普通的view的parent是他的容器布局捐凭,DecorView的parent是ViewRootImpl,在
root.setView(view, wparams, panelParentView);
這個(gè)方法執(zhí)行中,進(jìn)行了parent綁定ViewRootImpl凳鬓。
執(zhí)行完之后茁肠,在通過(guò)其他方式顯示在屏幕上。