【Android视图系统】对Activity、Window、PhoneWindow、Decor以及ViewRootImpl的理解

  • Post author:
  • Post category:其他




视图系统笔记




Activity:

它是一个负责与用户交互的组件,依靠

Instrumentation

与外部通信和分发生命周期,依靠

Window

来显示视图



创建时机:

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

抽象类,它是用来生成

PhoneWindow

的;另一种是窗口,它是一个抽象概念,是用来承载一棵控件树的,在客户端的实际存在形式是一棵

View树(包含ViewRootImpl)

,在服务端的实际存在形式是

WindowState




PhoneWindow


我理解的

PhoneWindow

除了为

Activity

做减负工作外,其中一个功能是为了给让

DecorView

的事件能够传递到

Activity

,它和

DecorView

并不能理解为包含关系(但是可以理解为

Window

包含

DecorView

)。例如

PopupWindow

就没有

PhoneWindow

,因此它的事件是由

ViewGroup

直接处理的



创建时机:

Activity # attach

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        //关联Activity
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);




Decor



Decor

应该是一个概念,它代表了

顶级View

,可以分类为

DecorView



ViewGroup

,虽然

DecorView

也是继承自

FrameLayout

,但是因为它持有了

PhoneWindow

(而且实现了

WindowCallBack

接口),从而让它在事件分发上有别于

PopupWindow

这一类以

ViewGroup



Decor

的窗口



创建时机:

Activity # onCreate # setContentView(PhoneWindow # setContentView)

        if (mContentParent == null) {
        	//创建Decor
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }




ViewRootImpl


虽然它实现了

ViewParent

,但是实际它并不能称之为

父View

,它负责着这个窗口所对应控件树的一些功能:事件分发、视图绘制、关联

Decor



WMS



创建时机:

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();
        }



版权声明:本文为qq_38872414原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。