视图系统笔记
Activity:
Activity:
它是一个负责与用户交互的组件,依靠
Instrumentation
与外部通信和分发生命周期,依靠
Window
来显示视图
创建时机:
ActivityThread # performLauchActivity
ActivityThread # performLauchActivity
ContextImpl appContext = createBaseContextForActivity(r);
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);
}
}
Window
:
Window
我将它理解成两种含义:一种是
Window
抽象类,它是用来生成
PhoneWindow
的;另一种是窗口,它是一个抽象概念,是用来承载一棵控件树的,在客户端的实际存在形式是一棵
View树(包含ViewRootImpl)
,在服务端的实际存在形式是
WindowState
PhoneWindow
:
PhoneWindow
我理解的
PhoneWindow
除了为
Activity
做减负工作外,其中一个功能是为了给让
DecorView
的事件能够传递到
Activity
,它和
DecorView
并不能理解为包含关系(但是可以理解为
Window
包含
DecorView
)。例如
PopupWindow
就没有
PhoneWindow
,因此它的事件是由
ViewGroup
直接处理的
创建时机:
Activity # attach
Activity # attach
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
//关联Activity
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
Decor
:
Decor
Decor
应该是一个概念,它代表了
顶级View
,可以分类为
DecorView
和
ViewGroup
,虽然
DecorView
也是继承自
FrameLayout
,但是因为它持有了
PhoneWindow
(而且实现了
WindowCallBack
接口),从而让它在事件分发上有别于
PopupWindow
这一类以
ViewGroup
为
Decor
的窗口
创建时机:
Activity # onCreate # setContentView(PhoneWindow # setContentView)
Activity # onCreate # setContentView(PhoneWindow # setContentView)
if (mContentParent == null) {
//创建Decor
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
ViewRootImpl
:
ViewRootImpl
虽然它实现了
ViewParent
,但是实际它并不能称之为
父View
,它负责着这个窗口所对应控件树的一些功能:事件分发、视图绘制、关联
Decor
和
WMS
创建时机:
ActivityThread # handleResumeActivity
ActivityThread # handleResumeActivity
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//调用到WindowManagerGlobal的addView
wm.addView(decor, l);
}
...
//在resume之后才有window,才设置为visible,所以这时候才会显示
//而且,resume后ViewRootImpl才存在,也就是说在之前的生命周期是不可以做视图绘制的,调用了
//invalidate或者requestLayout后也是不生效的
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}