前言
这篇文章主要讲Android设备从系统启动到Launcher界面(手机桌面)
、点击app图标应用启动流程
、View绘制流程
,这一整个流程进行了梳理。先来看下整体的流程图:
接下来我会分模块讲,每一个序号都会稍微
详细讲下它们,废话不多说,进入正题。
系统开机到Launcher显示流程
1、当android系统开机时,系统的引导芯片代码
会从预定义的地方(在ROM)开始执行,会去加载引导程序BootLoader
到RAM中,然后执行BootLoader
。引导程序是Android操作系统被拉起来之前的一个程序,它的作用就是把android系统拉起运行,也就是把linux内核启动。
2、当 Linux 内核启动后会初始化各种软硬件环境,加载驱动程序,挂载根文件系统,Linux 内核加载的准备完毕后就开始加载一些特定的程序(进程)了。第一个加载的就是 init 进程
。
3、init进程是Linux系统中用户空间的第一个进程
,进程号固定为1。内核启动后,在用户空间启动init进程,并调用init中的main()方法
。接着去解析init.rc文件,去启动Zygote进程
。
4、Zygote
进程是由init
进程解析init.rc
脚本创建的;
①首先会创建一个java虚拟机实例,然后注册JNI方法,最后通过JNI调用进入Java世界来到
ZygoteInit.main
方法;②在Java世界中,
给Zygote注册了socket用于进程间通信
,预加载一些通用的类和资源(system/etc/preloaded-c]asses 文件中的类、drawable和color资源、opengl等);③ 启动
system_server进程
后,zygote
进程继续循环等待孵化创建新的进程。
5、在Android 系统中大约有 80 个系统服务,都是由SystemServer
进程来创建的。作为一个应用开发者来说,需要特别熟悉的大概有这么四个: ActivityManagerService
、WindowManagerService
、PackageManagerService
和InputManagerService
,也就是我们常说的 AMS
、WMS
、PMS
和IMS
。
6、系统服务启动后都会交给ServiceManager
来管理,即像AMS
、WMS
、PMS
等服务,是在System_Server
进程里的(创建的),但是却交给了ServiceManager
去管理。
7、在AMS被启动后,随后会调用AMS
的systemReady()
方法,这是启动Launcher的入口。
到这之后,我们就能看到Launcher被启动起来了,也就是看到我们的手机桌面。
Launcher启动应用流程
8、当我们点击Launcher上的应用图标后,会产生input事件。这些input事件会先经过SystemServer
里的2个native循环线程
进行读取分发,分别是InputReader
负责读取
input事件,InputDispatcher
负责分发
input事件,最后会分发给Launcher来处理。
9、Launcher收到input事件后,会去调用AMS.startActivity()
来启动新的应用进程,这期间会先让Launcher进入Pause状态,接着通过socket
通信,通知Zygote进程
去fork
新的应用进程。
10、Zygote
接收到AMS
传过来的信息后,就会去fork应用进程,并进行应用进程的初始化,体现在ZygoteInit.zygoteInit()
方法里:
①设置默认的java异常处理机制(通过RuntimeInit.commonInit()设置);
②JNI调用启动进程的binder线程池;
③通过反射创建
ActivityThread对象
,并调用它的main
入口方法。
11、通过ZygoteInit.zygoteInit()
方法后,ActivityThread.main()
就会被调用到。
12、在ActivityThread.main()
先是创建Looper、MessageQueue、然后调用ActivityThread.attach()
方法,把自己注册到AMS中,方便AMS管理自己、最后启动Looper消息循环。
13、刚刚讲了,会调用ActivityThread.attach()
方法去AMS里注册, 最后会调用到AMS的attachApplicationLocked()
方法,在这个方法里,主要就是做Application
的创建,以及Activity
的创建。
14、先是Application
的创建,兜兜转转会又走到ActivityThread里的内部类ApplicationThread
,调用到它的bindApplication()
方法,里面主要发了个Handle消息,执行到了handleBindApplication()
,这个方法主要做的事情有:
①创建Application的context;
②触发ART虚拟机加载应用APK的Dex文件到内存中,加载APK的Resource资源;
③
执行Application的onCreate()
。
15、Application创建完后,就要去创建Activity了,主要是走了两个方法,分别是LauncherActivityItem
和ResumeActivityItem
。
(1)LauncherActivityItem
主要做了:
①创建Activity的context;
②反射创建Activity对象,执行Activity的attach(),创建PhoneWindow对象,为其配置WindowManager;
③执行Activity的onCreate(),并在setContentView()中,创建DecorView对象。
(2)ResumeActivityItem
主要做了:
①执行Activity的onResume();
②调用wm.addView(),即执行了WindowManager的addView(),addView方法里创建了
ViewRootImpl
对象,并执行了ViewRootImpl
的setView()
函数,开始UI界面的绘制工作。
到这后,应用的启动流程就到这,后面就是View的绘制流程
了。
View绘制流程
我还画了另外一张图,两张图可以交替看看:
16、来到ViewRootImpl
的setView()
方法后,主要走它里面的requestLayout()
方法。
17、requestLayout()
里面主要3件事。
18、分别是:
①
checkThread()
检查是否是在主线程,不在的话,会抛异常;②
getQueue.postSyncBarrier()
,向消息队列里加入一条屏障消息,用来屏蔽同步消息,保证UI绘制消息(它是异步消息的,所以不会被屏蔽)能优先进行;③
mChoregrapher.postCallback()
,这里主要是去向底层SurfaceFlinger请求Vsync(垂直同步信号),收到信号后,会回调到doFrame()
方法。
19、在doFrame()
里,会执行到doTraversals()
,一路执行到performTraversals()
。
21、最后就是我们熟悉的measure()
、layout()
、draw()
。
22、draw()
之后,画面还没出来,还需要经过底层的渲染合成之后,画面才会真正显示出来。