android高级UI之UI绘制流程(整体启动流程)

对于Android UI的学习在之前也针对性的进行过一些博客记录,但是还是没能系统全面的进行深入,有些零散,而在Android应用开发中它又是非常之重要的“硬”技能,所以接下来重新定下目标,要对它进行全面系统深入的再学习总结之路,目标是不管是对于面试还是实际工作中只要是涉及到UI效果这块都能做到心中有数,来对这块的硬技能的护城河加固再加固,对于新目标的开篇少了不要对UI绘制流程有一个整体的了解,这里是参考https://www.jianshu.com/p/0f6b4bc86c7b这位大神的简书为向导进行学习,拿来不可耻,但是重点是要利用网络上的各种好资源为自己所用,形成自己的知识体系。费话不多说,全面开启UI的系统学习。

先来引用博主开篇所说:

思路很清晰,所以接下来就来搞清楚这三个疑问则为这篇博文的全部内容。

分析前提示:

这次分析源码最好有以下基础:

1、Handler机制,之前总结过一篇:https://www.cnblogs.com/webor2006/p/11630538.html

2、Binder机制,之前总结过二篇:https://www.cnblogs.com/webor2006/p/11741743.htmlhttps://www.cnblogs.com/webor2006/p/11811650.html

1.Android程序是如何启动,Activity生命周期如何调用?

对于APP启动时都会知道它会调用ActivityThread.main()方法,在之前的Android Framework层源码的分析中也多次看到了,下面还是从它分析起:

此时则会调用到这个类的attach()方法,查看里面的核心代码:

此时咱们看一下ActivityManager.getService()的细节:

关于Binder机制这块就不多说了,很明显可以看到ActivityManager是由系统服务所调用管理,并且通过在binder接口当中进行调用,这也是为什么我们讲Activity是跨进程访问的原因。下面咱们来看一下IActivityManager这个AIDL中的asInterface()的具体细节。发现在Android Studio中打不开打,这里引用博主的图:

此时再回到主流上来继续往下分析:

其中mAppThread为:

此时来看一下它的细节:

还是看不到它的源码,这里继续引用博主的:

attachApplication在这里的作用其实实际上是ActivityThread通过attach获取到,然后将applciationThread将其关联,把activity相关信息存储在applciationThread里面,apllicationThread的类为activity的各种状态做了相对应的准备工作。
此时咱们得将焦点定位到ApplicationThread这个类来看进一步的细节,它是ActivityThread的一个内部类:

然后大致纵览一下ApplicationThread中的方法,里面有很多schedule开头的方法:

貌似跟咱们的Activity的生命周期有关系,其中有一个跟启动Activity相关的方法:

其中在发送Handler消息时生成了一个ActivityClientRecord,这其实就是我们的Activity,好,接下来得处理这个LAUNCH_ACTIVITY消息了,如下:

也就是说咱们的Activity是由ApplicationThread来通过Handler来进行启动的,下面则来看一下这个handleLaunchActivity()的具体启动细节:

好,再来看一下这个方法的细节:

然后再调用了Activity的attach方法:

然后再往下看,则会看到调用Activity.onCreate()的身影:

好,到目前咱们对于Application到Activity的启动流程已经有了一个整体的了解,接下来则需要将焦点关注在setContentView()是如何将我们的布局xml文件加载进来的了。

2.在Activity.onCreate()当中我们的setContentView是如何将UI文件加载?

咱们直接从入口开始分析:

其中这个getWindow()则是咱们都熟知的PhoneWindow,所以直接定位到PhoneWindow.setContentView(),看一下核心代码:

这里再一下installDecor()的细节:

其中对于mDecor和mContentParent的定义:

好,下面来瞅一下生成的细节:

没啥,直接new了一个DecorView,好再来看另一个生成细节:

好,继续往下则可以看到貌似开始再选择xml布局文件了:

而关于Activity、Window、PhoneWindow、DecorView、View之间的关系如博主描述的:

总结一下installDector()这个方法它其实实际上是在初始化两个视图容器,然后加载系统的R资源及特征,产生了一个基本布局。

好再回到主流程继续往下分析,也就是这块:

具体它的解析细节看一下流程图:

具体解析细节这里就不看了,重点是对整个的UI绘制流程有一个了解。至此对于我们的xml布局文件是怎么加载的流程就清楚了,接下来则得看一下这些布局加载进来之后是如何呈现到手机上的。

3.UI是如何绘制的?

那绘制流程从哪分析起呢?很显然是从Activity.onResume()这块分析起,而起点当然还是在ActivityThread的那个H中了:

其中它里面会将咱们的view添加到WindowManager中,如下:

此时查看一下这个addView的细节:

 

其中WindowManager接口就继承了这个接口,而它的具体实现是WindowManagerImpl,所以:

其中mGlobal为:

它的核心实现为:

其中mView、mRoots、mParams三个成员变量为:

mViews保存的是View对象,DecorView

mRoots保存和顶层View关联的ViewRootImpl对象

mParams保存的是创建顶层View的layout参数。

而WindowManagerGlobal类也负责和WMS通信。

好,回到主流程继续:

跟进去看一下它的核心代码:

也就是说将ViewRoot作为了View的Parent,好,注意了,绘制的核心流程就要到了,此时需要回到setContentView的代码来了:

其实setLayoutParams它里面就涉及到绘制流程的代码了:

好,再来看一下它里面的细节:

而mParent在之前已经分析过了,叫ViewRootImpl,所以转到它里面来看一下:

这里就正式进入UI绘制的流程了,所以接下来再来看一下它的细节:

跟进去:

关于这个View的测量细节下一次再来分析,目前先只把整个绘制流程给搞通,好,回到主流程继续分析:

接着再进行布局了,关于具体布局的系统实现细节这里也不分析了,待之后再进行,还是往下分析主流程,不然很容易绕晕了:

对于上面绘制的大概流程用图再来回顾一下:

至此,对于整个绘制的完整核心流程就分析完了,不过对于具体View的测量、布局、绘制的流程这里还没开始分析,待下次再继续。

posted on 2019-11-11 23:04  cexo  阅读(909)  评论(0编辑  收藏  举报

导航