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

2023年 9月 21日 28.9k 0

前言

这篇文章主要讲Android设备从系统启动到Launcher界面(手机桌面)点击app图标应用启动流程View绘制流程,这一整个流程进行了梳理。先来看下整体的流程图:

image.png
image.png
image.png

接下来我会分模块讲,每一个序号都会稍微详细讲下它们,废话不多说,进入正题。

系统开机到Launcher显示流程

image.png
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启动应用流程

image.png

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绘制流程

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

image.png

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()之后,画面还没出来,还需要经过底层的渲染合成之后,画面才会真正显示出来。

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论