App启动绘制流程

一、Window、DecorView、ViewRoot、WIndowManager关系

在Activity的onCreate中通过setContentView加载完布局,但并未对布局文件中的控件进行测量、布局、绘制。从Acitivity的各个生命周期可知,在onCreate时Activity并不可见,onStart虽然可见,但并未显示在前台,无法与用户进行操作,因此google将测量、布局、绘制流程放在了onResume中。回看ActivityThread的handleResumeActivity

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
   
   
            //获取DecorView
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            //获取ViewManager,其实是WindowManager
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
   
   
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
   
   
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
   
   
                if (!a.mWindowAdded) {
   
   
                    a.mWindowAdded = true;
                   //将DeocrView添加到WindowManager 
                    wm.addView(decor, l);
                } else {
   
   
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }

看到 wm.addView(decor, l);跟进ViewManager发现是一个接口,其实现类为WindowManager,但WindowMaanger同样也是接口,其具体实现类为WindowManagerImpl。

//该类控制布局添加、移除、更新,类似于控制者
public interface ViewManager
{
   
   
    /**
     * Assign the passed LayoutParams to the passed View and add the view to the window.
     * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming
     * errors, such as adding a second view to a window without removing the first view.
     * <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a
     * secondary {@link Display} and the specified display can't be found
     * (see {@link android.app.Presentation}).
     * @param view The view to be added to this window.
     * @param params The LayoutParams to assign to view.
     */
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

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

在WindowManagerImpl的addView中看到继续调用WindowManagerGlobal的addView,此处省略一些代码,看主要的,view是DecorView、root是ViewRootImpl、wparams是WindowManager.LayoutParams。

从上一篇文章中我们了解到,每一个Acitcity持有一个Window、每个Window又会持有一个DecorView、而DecorView是所有布局控件的父布局控件。试想一下,既然这样,那么当我们的Acitivity退出时,那么DecorView是不是应该被设置为GONE呢,而GONE被设置为了GONE,那么若是像Toast、Dialog等全局悬浮框怎么办,应该放在哪里呢?
为了解决这种情况,每个DecorView都会由单独一个ViewRootImpl进行管理,而WindowManagerImpl管理和多个ViewRootImpl,最终WindowManagerGlobal管理Android中的所有Window.
在这里插入图片描述

@UnsupportedAppUsage
    private final ArrayList<View> mViews = new ArrayList<View>();
    @UnsupportedAppUsage
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值