Android屏幕的框架

Activity與PhoneWindow與DecorView關(guān)系

Window
1.Windows是一個接口,實現(xiàn)它的是PhoneWindow
2.WindowManager創(chuàng)建一個window,WindowManager 為每一個window創(chuàng)建一個surface,并把該surface傳遞給應用以便應用在上面繪制,一個應用有很多Window。
3.Window是屏幕上用于繪制各種UI元素(比如Button,TextView)及響應用戶輸入事件(鍵盤事件)的一個矩形區(qū)域,它獨立繪制,不與其他界面產(chǎn)生影。
4.在Android系統(tǒng)中,每個Window是獨占一個Surface實例的顯示區(qū)域,每個窗口的Surface由WindowManagerService分配。
每個Window都對應著一個View和一個ViewRootImpl,Window和View通過ViewRootImpl來建立聯(lián)系,對于Activity來說,ViewRootImpl是連接WindowManager和DecorView的紐帶,繪制的入口是由ViewRootImpl的performTraversals方法來發(fā)起Measure,Layout,Draw等流程的
5.Window 是 Android 中窗口的宏觀定義,主要是管理 View 的創(chuàng)建,以及與 ViewRootImpl 的交互,將 Activity 與 View 解耦
DecorView
這個是根布局,包含了ActionBar,它就是我們看到的標題欄,另一個是ContentView(窗口內(nèi)容的容器),DecorView繼承了FragmentLayout,Activity生命周期的起點——onCreate回調(diào)方法里使用setContentView就是成了它的子View。每個Activity都與一個PhoneWindow相關(guān)聯(lián),用戶界面則由PhoneWindow所承載,
ActionBar

另一個是ContentView

ViewRootImpl
實現(xiàn)了ViewParent,對View的整個具體操作流程,是連接WindowManager和DecorView的紐帶
1.構(gòu)造方法
public ViewRootImpl(Context context, Display display) {
String processorOverrideName = context.getResources().getString(
R.string.config_inputEventCompatProcessorOverrideClassName);
if (processorOverrideName.isEmpty()) {
// No compatibility processor override, using default.
mInputCompatProcessor = new InputEventCompatProcessor(context);
} else {
InputEventCompatProcessor compatProcessor = null;
try {
final Class<? extends InputEventCompatProcessor> klass =
(Class<? extends InputEventCompatProcessor>) Class.forName(
processorOverrideName);
compatProcessor = klass.getConstructor(Context.class).newInstance(context);
} catch (Exception e) {
Log.e(TAG, "Unable to create the InputEventCompatProcessor. ", e);
} finally {
mInputCompatProcessor = compatProcessor;
}
}
if (!sCompatibilityDone) {
sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.P;
sCompatibilityDone = true;
}
loadSystemProperties();
}
2.在WindowManagerGlobal中實例化
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
ViewRootImpl root;
View panelParentView = null;
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
3.WindowManagerImpl中調(diào)用了addView
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
4.PhoneWindow的setContentView()調(diào)用了步驟3
public void setContentView(View view, ViewGroup.LayoutParams params) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
view.setLayoutParams(params);
final Scene newScene = new Scene(mContentParent, view);
transitionTo(newScene);
} else {
mContentParent.addView(view, params);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
5.Activity的setContext()就是這個
public void setContentView(View view) {
getWindow().setContentView(view);
initWindowDecorActionBar();
}
總結(jié)1:由上面分析是連接WindowManager和DecorView的紐帶,Activity中的setContentView就是成了DecorView它的子View
6.WindowManagerImpl addView同時也在ScrollView調(diào)用
@Override
public void addView(View child) {
if (getChildCount() > 0) {
throw new IllegalStateException("ScrollView can host only one direct child");
}
super.addView(child);
}
總結(jié)2:ViewRootImpl管理DecorView的子類增改刪
WindowManager窗口管理
管理窗口的一些狀態(tài)屬性(view 的增加,刪除,窗口位置,更新等等),它管理window和WindowManagerService交互,由ViewRoot完成。主要的方法有:addview(),updateViewLayout();removeView()。
WindowManager是一個接口,WindowManagerImpl 是它的實現(xiàn)類。
WindowManager 里面維護了三個變量:mViews(根view),mRoots(viewroot),mParams(一些相關(guān)變量),由 WindowManagerGlobal 維護它們。
WindowManagerService
對系統(tǒng)中的所有窗口進行管理,它和WindowManager區(qū)別是WindowManager管理的是單獨的窗口,而WindowManagerService需要管理所有的窗口。