先了解下幾個(gè)概念
Window
1.Window是頂級(jí)窗口外觀和行為策略的抽象基類(lèi)。 是被添加到WindowManager的頂級(jí)視圖良狈。
2.它提供了標(biāo)準(zhǔn)的 UI 策略后添,例如背景、標(biāo)題區(qū)域薪丁、默認(rèn)鍵處理等略遇西。
3.目前僅有的實(shí)現(xiàn)類(lèi)是PhoneWindow馅精。
4.View(Activity、Toast粱檀、Dialog)需要依賴(lài)于Window
WindowManager
1.Window的管理者洲敢,或者說(shuō),Window中View的管理者茄蚯,Window所需要展示的內(nèi)容是由View來(lái)承載的
2.它的具體實(shí)現(xiàn)是WindowManagerImpl压彭,用getSystemService(Context.WINDOW_SERVICE)來(lái)獲取
3.繼承ViewManager
WindowManagerImpl在SystemServiceRegistry類(lèi)中創(chuàng)建
static {
...
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx);
}});
...
通過(guò)getSystemService(Context.WINDOW_SERVICE)獲取
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManagerService
1.系統(tǒng)服務(wù),繼承繼承 IWindowManager.Stub第队,負(fù)責(zé)協(xié)調(diào)Window的層級(jí)哮塞、顯示及事件派發(fā)等
2.WindowManager是本地端的管理者刨秆,負(fù)責(zé)與WindowManagerService進(jìn)行交互凳谦,這是一個(gè)IPC過(guò)程
在SystemServer啟動(dòng)的時(shí)候,會(huì)創(chuàng)建WindowManagerService并注冊(cè)到ServiceManager中:
// 在main()方法中會(huì)調(diào)用startOtherServices()
private void startOtherServices() {
...
wm = WindowManagerService.main(context, inputManager, mFactoryTestMode !=
FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
}
WindowManagerGlobal
1.WindowManagerImpl實(shí)際上是將工作委托給了WindowManagerGlobal來(lái)完成
2.WindowManagerGlobal中主要對(duì)View衡未、ViewRootImpl以及LayoutParams進(jìn)行管理
// view
private final ArrayList<View> mViews = new ArrayList<View>();
// ViewRootImpl
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
// 參數(shù)
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>();
// 即將移除的view
private final ArraySet<View> mDyingViews = new ArraySet<View>();
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
...
}
ViewRootImpl
1.ViewRootImpl不是View尸执,它是頂級(jí)View的管理者。
2.每一個(gè)ViewRootImpl 都對(duì)應(yīng)著一個(gè)ViewTree 缓醋,通過(guò)它來(lái)完成View的繪制及顯示過(guò)程如失。
3.Window與View通過(guò)ViewRootImpl建立起聯(lián)系
Window創(chuàng)建過(guò)程
ActivityThread
啟動(dòng)Activity時(shí),ActivityThread會(huì)處理以下幾件事:
1.拿到Activity一些組件信息送粱,然后通過(guò)Instrumentation反射創(chuàng)建Activity
2.調(diào)用Activity的attach來(lái)完成Window的創(chuàng)建等工作褪贵,
3.回調(diào)onCreate生命周期方法。
4.回調(diào)onResume
5.通過(guò)WindowManager.addView添加Window(具體看后面講解)
public final class ActivityThread extends ClientTransactionHandler {
// 保存所有Activity的相關(guān)信息
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
// Activity啟動(dòng)
@Override
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
// 創(chuàng)建activity之前進(jìn)行WindowManagerGlobal的初始化
WindowManagerGlobal.initialize();
// 創(chuàng)建activity 及調(diào)用onCreate
Activity a = performLaunchActivity(r, customIntent);
}
// Activity啟動(dòng), onCreate
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
ActivityInfo aInfo = r.activityInfo;
// ... 拿到相關(guān)package抗俄、組件等信息
// 創(chuàng)建上下文對(duì)象脆丁,實(shí)際創(chuàng)建的是ContextImpl對(duì)象
ContextImpl appContext = createBaseContextForActivity(r);
// ... 反射來(lái)創(chuàng)建Activity
Activity activity = ...
try {
// LoadedApk創(chuàng)建Application對(duì)象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
Window window = null;
// activity 重啟,拿到上一次的Window动雹,并在PhoneWindow復(fù)用之前的DecorView
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// 這里通過(guò)調(diào)用 activity.attach 創(chuàng)建一個(gè)PhoneWindow
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);
...
// 回調(diào)onCreate
mInstrumentation.callActivityOnCreate(activity, r.state);
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
}
...
return activity;
}
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
// onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
return;
}
if (r.window == null && !a.mFinished && willBeVisible) {
// 獲取的Window為PhoneWindow
r.window = r.activity.getWindow();
// 獲取DecorView
View decor = r.window.getDecorView();
// 設(shè)為不可見(jiàn)
decor.setVisibility(View.INVISIBLE);
// 通過(guò)WindowManager添加到窗體
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
wm.addView(decor, l);
...
}
...
if (r.activity.mVisibleFromClient) {
// 會(huì)調(diào)用decor.setVisibility(View.VISIBLE)設(shè)置為可見(jiàn)
r.activity.makeVisible();
}
}
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
final ActivityClientRecord r = mActivities.get(token);
...
// onResume
r.activity.performResume(r.startsNotResumed, reason);
...
}
// Activity內(nèi)部類(lèi)槽卫,每一個(gè)Activity對(duì)應(yīng)一個(gè)ActivityClientRecord
// 存儲(chǔ)在mActivities中
public static final class ActivityClientRecord {
// activity的token
public IBinder token;
Intent intent;
// onSaveInstance數(shù)據(jù)保存在這里
Bundle state;
Activity activity;
// activity附加到的Window,handleResumeActivity進(jìn)行賦值
Window window;
// 保存由于配置更改而導(dǎo)致頁(yè)面銷(xiāo)毀時(shí)的一些狀態(tài)胰蝠,包括ViewModelStore歼培,F(xiàn)ragment等
Activity.NonConfigurationInstances lastNonConfigurationInstances;
// activity重啟,拿到上一次的Window茸塞,handleLaunchActivity初始化
Window mPendingRemoveWindow;
// activity重啟躲庄,拿到上一次的WindowManager,handleLaunchActivity初始化
WindowManager mPendingRemoveWindowManager;
}
}
// Activity靜態(tài)內(nèi)部類(lèi)钾虐,保存由于配置更改而導(dǎo)致頁(yè)面銷(xiāo)毀時(shí)的一些狀態(tài)
static final class NonConfigurationInstances {
// 保存ViewModelStore
Object activity;
// 保存Fragment
HashMap<String, Object> children;
FragmentManagerNonConfig fragments;
ArrayMap<String, LoaderManager> loaders;
VoiceInteractor voiceInteractor;
}
// ComponentActivity靜態(tài)內(nèi)部類(lèi)读跷,用于保存ViewModelStore
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
Activity
1.完成PhoneWindow的創(chuàng)建
2.通過(guò)setContentView,在PhoneWindow中創(chuàng)建了DecorView(具體看后面)
public class Activity extends ...{
private Window mWindow;
private WindowManager mWindowManager;
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
// 創(chuàng)建Window(PhoneWindow)禾唁,并傳入重啟前的window
mWindow = new PhoneWindow(this, window);
// 設(shè)置各種Callback
mWindow.setWindowControllerCallback(this);
// this即activity效览,存在Window的mCallback中
mWindow.setCallback(this);
...
// 設(shè)置WindowManager无切,實(shí)際上設(shè)置的是WindowManagerImpl
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();
...
}
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
initWindowDecorActionBar();
}
}
PhoneWindow
1.創(chuàng)建DecorView
2.將View填充到mContentParent中
public class PhoneWindow extends Window {
public PhoneWindow(Context context, Window preservedWindow,
ActivityConfigCallback activityConfigCallback) {
this(context);
// 復(fù)用重啟前的View
if (preservedWindow != null) {
mDecor = (DecorView) preservedWindow.getDecorView();
...
}
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
// mContentParent為ID_ANDROID_CONTENT
if (mContentParent == null) {
// 創(chuàng)建DecorView
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
...
// 將Activity.setContentView添加的布局,填充到mContentParent中
mContentParent.addView(view, params);
...
}
// 在ActivityThread的handleResumeActivity中會(huì)獲取DecorView添加到WindowManager中
// 如果沒(méi)調(diào)用setContentView丐枉,當(dāng)調(diào)用getDecorView會(huì)默認(rèn)創(chuàng)建一個(gè)DecorView
// 所以不管是那種情況都會(huì)調(diào)用導(dǎo)致DecorView的創(chuàng)建哆键,不過(guò)只會(huì)創(chuàng)建一次
@Override
public final @NonNull View getDecorView() {
if (mDecor == null || mForceDecorInstall) {
installDecor();
}
return mDecor;
}
// 創(chuàng)建 DecorView
private void installDecor() {
if (mDecor == null) {
// 用來(lái)創(chuàng)建DecorView
mDecor = generateDecor(-1);
...
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
// 內(nèi)容布局,android.R.content
mContentParent = generateLayout(mDecor);
...
}
// 設(shè)置標(biāo)題樣式等
...
}
}
WindowManagerGlobal
由ActivityThread -> handleResumeActivity 可知:
在onResume之后瘦锹,將DecorView添加到WindowManage(WindowManagerGlobal)
WindowManagerGlobal創(chuàng)建ViewRootImpl籍嘹,并將DecorView設(shè)置到ViewRootImpl
WindowManager.LayoutParams l = r.window.getAttributes();
wm.addView(decor, l);
public final class WindowManagerGlobal {
private static IWindowManager sWindowManagerService;
private static IWindowSession sWindowSession;
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
...
// 創(chuàng)建ViewRootImpl
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
...
// 給ViewRootImpl添加DecorView
// 最后執(zhí)行這個(gè)操作,是因?yàn)樗鼤?huì)觸發(fā)消息
root.setView(view, wparams, panelParentView, userId);
}
// 通過(guò)wms創(chuàng)建一個(gè)類(lèi)型為Session的Binder對(duì)象
public static IWindowSession getWindowSession() {
if (sWindowSession == null) {
...
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
});
}
return sWindowSession;
}
}
// 獲取wms的代理
public static IWindowManager getWindowManagerService() {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
...
return sWindowManagerService;
}
}
}
ViewRootImpl
通過(guò)IWindowSession于WindowManagerService交互弯院,完成window的添加等操作
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
// mWindowSession是一個(gè)通過(guò)WMS獲取的Binder對(duì)象辱士,真正的實(shí)現(xiàn)類(lèi)是Session
final IWindowSession mWindowSession;
View mView;
W mWindow = new W(this);
// mWindowSession初始化
public ViewRootImpl(Context context, Display display) {
this(context, display, WindowManagerGlobal.getWindowSession(), false);
}
// 將Window添加到窗口管理器
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
mView = view;
...
// 在添加到窗口管理器之前請(qǐng)求一次布局
// 以確保我們從系統(tǒng)接收任何其他事件之前進(jìn)行重新布局。
requestLayout();
// ViewRootImpl 通過(guò) IWindowSession 與 WMS 進(jìn)行交互的
// 這是一個(gè)IPC的過(guò)程听绳,基于Binder的跨進(jìn)程通信颂碘。
// 通過(guò)調(diào)用 addToDisplay, 將 mWindow 等參數(shù)傳遞給 WindowManagerService
// 內(nèi)部執(zhí)行Window的添加等操作
mWindowSession.addToDisplayAsUser(mWindow, ....);
...
// 將ViewRootImpl設(shè)置為DecorView的parent (繼承ViewParent)
view.assignParent(this);
...
}
static class W extends IWindow.Stub {
...
}
}
1.Window的添加是通過(guò)IWindowSession建立起與WMS的連接椅挣。
2.IWindowSession是一個(gè)Binder對(duì)象头岔,其實(shí)現(xiàn)是Session,Session內(nèi)部通過(guò)調(diào)用WMS的addWindow方法進(jìn)行
Window的添加等操作鼠证,Window的狀態(tài)保存到了WindowState中
3.當(dāng)應(yīng)用啟動(dòng)第一個(gè)activity的時(shí)候峡竣,會(huì)請(qǐng)求WMS服務(wù)建立Binder進(jìn)程間通信服務(wù),WMS創(chuàng)建一個(gè)類(lèi)型為
Session的Binder對(duì)象量九,并將這個(gè)Binder對(duì)象返回給應(yīng)用進(jìn)程
Window的添加大致流程:
-> WindowManager(WindowManagerImpl)
-> WindowManagerGlobal>addView
-> ViewRootImpl>setView>IWindowSession>addToDisplay
-> (IPC)Session>addToDisplay
-> WindowManagerService>addWindow
總結(jié)
1.Activity啟動(dòng)時(shí)适掰,由ActivityThread.handleLaunchActivity創(chuàng)建Activity,并執(zhí)行Activity.attach方法,
然后回調(diào)onCreate
2.Activity.attach創(chuàng)建一個(gè)PhoneWindow
3.PhoneWindow創(chuàng)建DecorView荠列,并將contentView添加到DecorView
4.ActivityThread.handleResumeActivity类浪,回調(diào)onResume,然后獲取window的DecorView添加到WM中
5.WM創(chuàng)建ViewRootImpl弯予,并調(diào)用ViewRootImpl.setView將DecorView設(shè)置到ViewRootImpl中
6.ViewRootImpl調(diào)用requestLayout()方法來(lái)請(qǐng)求繪制布局
7.ViewRootImpl通過(guò)WMS獲取Session的代理對(duì)象IWindowSession
8.IWindowSession將window的binder代理W添加到WMS中