【图文分析】Android系统启动到应用界面展示的全流程

前言

这篇文章主要讲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进程来创建的。作为一个应用开发者来说,需要特别熟悉的大概有这么四个: ActivityManagerServiceWindowManagerServicePackageManagerServiceInputManagerService,也就是我们常说的 AMSWMSPMSIMS

6、系统服务启动后都会交给ServiceManager来管理,即像AMSWMSPMS等服务,是在System_Server进程里的(创建的),但是却交给了ServiceManager去管理。

7、在AMS被启动后,随后会调用AMSsystemReady()方法,这是启动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了,主要是走了两个方法,分别是LauncherActivityItemResumeActivityItem

(1)LauncherActivityItem主要做了:

①创建Activity的context;

②反射创建Activity对象,执行Activity的attach(),创建PhoneWindow对象,为其配置WindowManager;

③执行Activity的onCreate(),并在setContentView()中,创建DecorView对象。

(2)ResumeActivityItem主要做了:

①执行Activity的onResume();

②调用wm.addView(),即执行了WindowManager的addView(),addView方法里创建了ViewRootImpl对象,并执行了ViewRootImplsetView()函数,开始UI界面的绘制工作。

到这后,应用的启动流程就到这,后面就是View的绘制流程了。

View绘制流程

我还画了另外一张图,两张图可以交替看看:

16、来到ViewRootImplsetView()方法后,主要走它里面的requestLayout()方法。

17、requestLayout()里面主要3件事。

18、分别是:

checkThread()检查是否是在主线程,不在的话,会抛异常;

getQueue.postSyncBarrier(),向消息队列里加入一条屏障消息,用来屏蔽同步消息,保证UI绘制消息(它是异步消息的,所以不会被屏蔽)能优先进行;

mChoregrapher.postCallback(),这里主要是去向底层SurfaceFlinger请求Vsync(垂直同步信号),收到信号后,会回调到doFrame()方法。

19、在doFrame()里,会执行到doTraversals(),一路执行到performTraversals()

21、最后就是我们熟悉的measure()layout()draw()

22、draw()之后,画面还没出来,还需要经过底层的渲染合成之后,画面才会真正显示出来。

相关推荐
太空漫步112 小时前
android社畜模拟器
android
海绵宝宝_4 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
凯文的内存6 小时前
android 定制mtp连接外设的设备名称
android·media·mtp·mtpserver
天若子6 小时前
Android今日头条的屏幕适配方案
android
林的快手8 小时前
伪类选择器
android·前端·css·chrome·ajax·html·json
望佑8 小时前
Tmp detached view should be removed from RecyclerView before it can be recycled
android
xvch10 小时前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
人民的石头14 小时前
Android系统开发 给system/app传包报错
android
yujunlong391914 小时前
android,flutter 混合开发,通信,传参
android·flutter·混合开发·enginegroup
rkmhr_sef14 小时前
万字详解 MySQL MGR 高可用集群搭建
android·mysql·adb