本篇文章對(duì)之前3篇描述的Activity、Window切端、View關(guān)系做個(gè)粗略的總結(jié)
在 Activity 創(chuàng)建過(guò)程中執(zhí)行 scheduleLaunchActivity() 之后便調(diào)用到了 handleLaunchActivity() 方法彻坛。
1 handleLaunchActivity內(nèi)調(diào)用performLaunchActivity()
//創(chuàng)建目標(biāo)Activity對(duì)象
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
2 執(zhí)行activity.attach()
//創(chuàng)建 PhoneWindow
mWindow = new PhoneWindow(this);
//與activity建立回調(diào)關(guān)聯(lián)
mWindow.setCallback(this);
//設(shè)置并獲取 WindowManagerImpl 對(duì)象
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();
針對(duì)WindowManager要多說(shuō)兩句,每個(gè) Activity 會(huì)有一個(gè) WindowManager 對(duì)象踏枣,這個(gè) mWindowManager 就是和 WindowManagerService 進(jìn)行通信昌屉,也是 WindowManagerService 識(shí)別 View 具體屬于那個(gè) Activity 的關(guān)鍵,創(chuàng)建時(shí)傳入 IBinder 類(lèi)型的 mToken茵瀑。
3 回調(diào) Activity.onCreate()
會(huì)執(zhí)行setContentView方法
installDecor(); 主要就是初始化了DecorView
mLayoutInflater.inflate(layoutResID, mContentParent);//將layout解析為View樹(shù)怠益,添加到DecorView的contentView部分
這時(shí)只是創(chuàng)建了 PhoneWindow,和DecorView瘾婿,但目前二者也沒(méi)有任何關(guān)系。
4. WindowManagerGlobal.addView()
在ActivityThread.performResumeActivity 中烤咧,調(diào)用 r.activity.performResume()偏陪,調(diào)用 r.activity.makeVisible(), makeVisible中:WindowManager 的 addView 的具體實(shí)現(xiàn)在 WindowManagerImpl 中.而 WindowManagerImpl 的 addView 又會(huì)調(diào)用 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è)app進(jìn)程共享一個(gè)WindowManagerGlobal,它是一個(gè)統(tǒng)籌大管家煮嫌,內(nèi)部方法主要是對(duì)View的處理 和 與 WMS的 IPC.
對(duì)View的處理交給它的得力助手ViewRootImpl:
5. ViewRootImpl setView()
以WindowManagerGlobal的addView為例笛谦,最終會(huì)調(diào)用ViewRootImpl setView()
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
…
//開(kāi)啟DecorView繪制流程
requestLayout();
...
//將DecorView添加到window上
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
...
}
}
兩張圖總結(jié)下:
總結(jié):
Activity主要作用還是生命周期的管理,Window是一個(gè)視圖容器昌阿,將Activity與View解耦饥脑,WindowManager統(tǒng)一管理View。
所以懦冰, Activity與window的關(guān)聯(lián)主要還是體現(xiàn)在生命周期的管理灶轰,和key touch事件回調(diào)上。 Window與View的關(guān)聯(lián)體現(xiàn)在對(duì)View視圖的處理上刷钢。
參考:
https://blog.csdn.net/freekiteyu/article/details/79408969