Android中的Window、ViewRoot和DecorView的关系

知识点:

1.Window、ViewRoot和DecorView的关系
2.DecorView是什么布局
3.DecorView什么时候显示

一、Window、ViewRoot和DecorView的关系

Android系统在启动Activity时,会先创建activity实例。在在activity实例中创建window实例,decorView便是window创建的。而ViewRoot则是链接window和decorView的纽带。
从源码的角度看,系统启动onResume之前,会调用ActivityThread的handleResumeActivity方法,

  @Override
  public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        
        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        if (r == null) {
            // We didn't actually resume the activity, so skipping any follow-up actions.
            return;
        }

        final Activity a = r.activity;//Activity实例

        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow(); // Winsow实例
            View decor = r.window.getDecorView(); // DecorView实例
            decor.setVisibility(View.INVISIBLE); // 默认不可见
            ViewManager wm = a.getWindowManager(); // WindowManager实例,ViewManager的子类
            WindowManager.LayoutParams l = r.window.getAttributes(); // Winsow布局参数
            a.mDecor = decor;

            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);  // 关联
                } 
            }
        } 

                           ······

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {

            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }

 }

在该方法中依次获取Activity实例、Winsow实例及其布局参数l、DecorView实例、WindowManager实例wm,并通过WindowManager的addView方法将DecorView和window关联起来。
具体如何关联的呢?
WindowManagerImpl对addView方法做了具体实现,

    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }

最终,WindowManagerGlobal完成了关联任务。代码如下:

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {

        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;

        ViewRootImpl root;
        View panelParentView = null;

        synchronized (mLock) {

            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            try {
                root.setView(view, wparams, panelParentView);
            } catch (RuntimeException e) {
               ...
            }
        }
    }

viewRoot通过setView方法,将DecorView和Window关联起来,它是纽带。
继续分析就会发现,Window最终只是需要DecorView在Z轴方向的位置信息。


关联逻辑

二、DecorView是什么布局

DecorView

三、DecorView什么时候显示

在完成关联之后,ActivityThread会调用Activity的makeVisible方法,显示DecorView

            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }

你可能感兴趣的:(Android中的Window、ViewRoot和DecorView的关系)