美文网首页
Android中的Window、ViewRoot和DecorVi

Android中的Window、ViewRoot和DecorVi

作者: 小天使999999 | 来源:发表于2020-07-03 02:01 被阅读0次

    知识点:

    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和DecorVi

          本文链接:https://www.haomeiwen.com/subject/llwdqktx.html