Activity,DecorView,PhoneWindow和ViewRoot的作用和相关关系
    
    1,Activity和Window 前者控制生命周期,window控制视图,前者可以没有后者那就相当于一个service,
       Activity和Window的第一次邂逅是在ActivityThread调用Activity的attach()函数时。创建一个PhoneWindow
        ....
       mWindow = PolicyManager.makeNewWindow(this);
       //当window接收系统发送给它的IO输入事件时,例如键盘和触摸屏事件,就可以转发给相应的Activity
       mWindow.setCallback(this);
       .....
       //设置本地窗口管理器
       mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
            
    2,Window,Activity和DecorView
       DecorView是FragmentLayout 的子类 ,被认为是android 视图树的根节点视图
       DecorView作为顶级View 一般包含一个竖向LinearLayout(具体跟android版本和主体有关)上边为标题栏下边为内容
       activity 通过setContentView来给 内容栏添加布局内容栏id为content
       (ViewGroup)findViewById(R.android.id.content)来得到content对应的layout(在应用层是无法调用R.android的)
       结果:Activity的setContentView实际上是调用了Window的setContentView方法。
       window生成 Window内部的原始顶级视图(DecorView)添加LinearLayout,style等生成contentParent,把setContentView的view 放入其中contentParent中 就是ContentParent 所显示的视图(呈现给用户的DecorView)为ContentRoot
       @Override
        public void setContentView(int layoutResID) {
            if (mContentParent == null) { //[window]如何没有DecorView,那么就新建一个
                installDecor(); //[window]
            } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
                mContentParent.removeAllViews();
            }
            ....
            //[window]第二步,将layout添加到mContentParent
            mLayoutInflater.inflate(layoutResID, mContentParent);
            .....
        }
        //[window]创建一个decorView
        private void installDecor() {
            if (mDecor == null) {
                mDecor = generateDecor(); //直接new出一个DecorView返回
                ....
            }
            if (mContentParent == null) {
                //[window] 这一步也是很重要的.
                mContentParent = generateLayout(mDecor); //mContentParent是setContentVIew的关键啊
                .....
                }
            ....
            }
        protected ViewGroup generateLayout(DecorView decor) {
            // Apply data from current theme.
            .......
            //[window] 根据不同的style生成不同的decorview啊
            View in = mLayoutInflater.inflate(layoutResource, null);
            // 加入到deco中,所以应该是其第一个child
            decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
            mContentRoot = (ViewGroup) in; //给DecorView的第一个child是mContentView
            // 这是获得所谓的content 
            ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
            }
            .....
            return contentParent;
        }
        那么,Activity中的mDecor是何时被赋值的?我们如何确定它和Widnow中的mDecor指向同一个对象呢?
        我们可以查看ActivityThread的 handleResumeActivity 函数,它负责处理Activity的resume阶段。在这个函数中,
        Android直接将Window中的DecorView实例赋值给Activity。
    
    3,Window,DecorView 和 ViewRoot
       ViewRoot可以被理解为“View树的管理者”——它有一个mView成员变量,它指向的对象和上文中Window和Activity的mDecor指向的对象是同一个对象
       ViewRoot对应ViewRootImpl类
       它是连接WindowManagerService和DecorView的纽带,View的三大流程(测量(measure),布局(layout),绘制(draw))均通过ViewRoot来完成。
       ViewRoot并不属于View树的一份子。从源码实现上来看,它既非View的子类,也非View的父类,但是,它实现了ViewParent接口,这让它可以作为View的名义上的父视图。
       RootView继承了Handler类,可以接收事件并分发,Android的所有触屏事件、按键事件、界面刷新等事件都是通过ViewRoot进行分发的
       
       那么,Window是什么时候被添加到WindowManager中的呢?我们回到ActivityThread的handleResumeActivity函数。我们都知道Activity的resume阶段就是要显示到屏幕上的阶段,在Activity也就是DecorView将要显示到屏幕时,系统才会调用addView方法。 
        // ActivityThread
        r.activity.makeVisible();

        //Activity
        //[windows] DecorView正式添加并显示
        void makeVisible() {
            if (!mWindowAdded) {
                ViewManager wm = getWindowManager();
                wm.addView(mDecor, getWindow().getAttributes());
                mWindowAdded = true;
            }
            mDecor.setVisibility(View.VISIBLE);
        }
        
     总结 ActivtyThread调用Activity attach时 创建PhoneWindow,在setcontentview 后 调用PhoneWindow.setcontentview,创建DecorView(Fragment子类,
     内含LinearLayout上边标题下内容),将view加入DecorView内容中,当Activity rusume时,也就是ActivityThread的handleResumeActivity函数时会调用makeVisible(),在通过WindowManager 提供的方法交由WindowManagerGloalal 创建RootView(RootViewlmpl)
     将decorView add到其列表中(,RootView通过requestLayout 异步刷新并scheduleTraversals绘制视图 通过WindowSession 来完成Window的添加(Wms IPC通讯)

     总结 activity>phoneWiddow->DectorView=(titleview(标题)+contentView)>contentView

更多相关文章

  1. android v13 的新特性
  2. 字节跳动面试官:Android源码的Binder权限是如何控制?
  3. android 使用Sax 读取xml
  4. 【Android(安卓)Developers Training】 7. 添加Action Buttons
  5. android事件分发(三)重要的函数requestDisallowInterceptTouchEven
  6. Android中onActivityResult方法总结
  7. Android(安卓)8.0 高通代码预制apk可卸载,恢复出厂设置apk可恢复
  8. ListView改变里面TextView的字体颜色
  9. Android(安卓)Studio阶段性学习总结_1

随机推荐

  1. 安卓视频播放器 一行代码快速实现视频播
  2. Android 匿名共享内存C++接口分析
  3. Android中Launcher实例
  4. android 广告栏 viewpager
  5. Android Studio使用教程(一)
  6. Android之Intent(二)
  7. Android2.2 API 中文文档系列(1)
  8. Android编译系统详解(三)——编译流程详
  9. Android跨线程消息机制
  10. Android 上八款优秀的开源游戏引擎