如果图片链接失败,请扫码查看文章详情。
Android Display Graphics系列文章-汇总
系列文章请扫关注公众号!
创建Activity
Activity是Android系统的应用组件,一般情况下,开发者显示的内容是通过Activity展示的。比如 使用Android studio创建一个空activity的demo,示例代码如下
这里的onCreate就调用到了Activity的onCreate,创建一个出来。
setContentView()用来绑定视图,将xml或java代码中的设置视图绑定到Activity上来。
Activity的创建呢,可以理解为3给个对象的创建:Window、DecorView、ViewRootImpl。
Window的创建
当用户从launcher界面点击一个应用时,Zygote收到相应请求后fork出一个子进程,这个子进程就是APP对应的进程。这个APP的入口函数就是ActivityThread的main函数:
一系列的调用流程是:
ActivityThread#main()初始化调用attach()
-->attach() 创建ApplicationThread,并跨进程传递给AMS管理
-->AMS通过ApplicationThread通知ActivityThread创建Activity
-->performLaunchActivity() new Activity && run attach()
-->Activity#attach() create Window对象
DecorView的创建
在Code para#1段 L18-L21行的代码调用了Activity的attach()和onCreate();
Activity activity = new Activity();
-->activity.attach();//回调attach
-->activity.onCreate();//回调Activity
开发者通常会在onCreate()方法中调用setContentView()设置视图文件。
流程如下:
Activity-->onCreate()-->setContentView()加载视图文件
-->setContentView()-->Window.setContentView()方法,传递视图
-->Window#setContentView()创建了顶级视图DecorView对象
-->为Activity寻找对应的主题文件,解析并添加为DecorView的子View,也就是mContentParent
-->将开发者指定的视图添加到mContentParent中
Step1:DecorView 是根Root View,也个FrameLayout,所以mWindow#setContentView()函数中最先将DecorView对象创建出来。
Step2:加载Activity使用的主题文件,并且将该主题作为子View添加到DecorView,这个子View就是mContentParent。
Step3:将我们设置的视图添加为mContentParent的子View,会有一个名为R.id.content的FrameLayout,这个里面才是包含我们设置的视图.
Code para#4
开发者设置的视图添加为子View的下一步,是回调Activity中onContentChanged()方法
当我们在Activity收到onContentChanged()回调的这一刻,说明DecorView已经创建完成
ViewRootImpl的创建
1.1和1.2分别让我们拥有了一个Window对象和一个DecorView对象。
Window对象中包含了DecorView对象,DecorView包含了我们设置的视图文件。
接下来的任务就是把该Window对象传递给WMS
和前两个阶段不同的是,第三阶段是在Activity的onResume()回调中被触发的
在ActivityThread通知完onResume()的下一步调用了makeVisible()方法
makeVisible()方法中,将会调用WindowManager#addView(mDecor)将视图传递给WMS
Code para#5
· Activity执行完onResume()以后,立刻调用makeVisible()方法准备将视图传递给WMS
· makeVisible()方法中,调用WindowManager#addView()
· 经过层层调用,最终由进程单例WindowManagerGlobal对象执行addView()方法
· WindowManagerGlobal#addView()中,创建了本章节主角:ViewRootImpl
· ViewRootImpl通过binder向wms添加窗口
WindowManagerImpl是WindowManager的最终实现类,它会调用到WindowManagerGlobal#addView()方法
而WindowManagerGlobal是全局单例,每个进程有且只有一个,也就是说
所有的Activity对应的Window都由WindowManagerGlobal进行管理
因此,WindowManagerGlobal会有两个关键集合:mViews和mRoots
mViews是保管着的DecorView的集合,mRoots是保管着ViewRootImpl的集合
保管着ViewRootImpl的集合?
DecorView是每个Activity的跟视图,ViewRootImpl是什么?
//对应一个Activity,关于视图的事件触发都在此
看看ViewRootImpl类中的三个成员变量:
- mView:DecorView让ViewRootImpl能够在事件来临时控制视图
- mSurface:让Activity拥有绘图的能力
- mChoreographer:让ViewRootImpl能够监听VSync信号
这个类几乎集齐了所有与视图相关的成员
/frameworks/base/core/java/android/view/WindowManagerGlobal.java
WindowManagerGlobal创建了ViewRootImpl对象后,把它保存到本地集合mRoots
接着调用ViewRootImpl#setView()方法添加视图,setView()中又调用addToDisplay()方法通过binder向WMS添加窗口
至此,Window对象的创建、DecorView的创建和ViewRootImpl的创建这三大阶段全部完成
我们来总结一下在创建Activity阶段发生的事情
· Activity中,创建PhoneWindow类型的Window对象
· Window中,创建DecorView对象,绑定setContentView传入的视图文件
· 调用WindowManager添加视图,准备把视图绑定到WMS
· 创建ViewRootImpl作为最终的执行者,将视图添加WM