android系统从systemserver开始的launcher启动详细流程

更新时间:2023-03-11 00:23:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

android系统启动流程

android系统启动流程

——从systemserver开始的launcher

目录

1 概述: ................................................................................................................................................... 2 2 systemserver工作内容分析 ......................................................................................................... 4

2.1 SystemServer类简述 ......................................................................................................... 4 2.2 ServerThread类简述 ......................................................................................................... 4 3 ActivityManagerService工作内容分析 .................................................................................... 6

3.1 ActivityManagerService之main .................................................................................. 7

3.1.1创建ActivityManagerService实例 .................................................................... 7 3.1.2 创建ActivityThread实例,获取全局Context ................................................ 8 3.1.3创建ActivityStackSupervisor实例 ................................................................... 10 3.1.4调用startRunning ................................................................................................. 10 3.2 ActivityManagerService之setSystemProcess ....................................................... 11 3.3. ActivityManagerService之setWindowManager ................................................. 12 3.4 ActivityManagerService之systemready ................................................................. 12

3.4.1 启动所有Persistent属性的APK ....................................................................... 13 3.4.2 启动launcher ........................................................................................................ 14

4 ActivityStackSupervisor启动launcher ................................................................................. 15

4.1首先回顾一下ActivityStackSupervisor实例的初始化 ............................................. 15 4.2 进入ActivityStackSupervisor.resumeTopActivitiesLocked ................................ 16 4.3 进入ActivityStack.resumeTopActivityLocked ........................................................ 16 4.4 回到ActivityStackSupervisor.resumeHomeActivity。 ........................................ 17 4.5 ActivityStackSupervisor.mProbeThread ................................................................... 17 4.6 ActivityStackSupervisor.mProbeHandler ................................................................. 18 4.7 回到ActivityManagerService.startHomeActivityLocked ................................... 18 4.8 ActivityStackSupervisor.startHomeActivity ............................................................ 19 4.9 ActivityStackSupervisor.startActivityUncheckedLocked ................................. 20 4.10 ActivityStack.startActivityLocked ............................................................................. 21

1 / 41

android系统启动流程

4.11 ActivityStackSupervisor.resumeTopActivitiesLocked ........................................ 22 4.12 ActivityStack.resumeTopActivityLocked ................................................................ 22 4.13 ActivityStackSupervisor.startSpecificActivityLocked ......................................... 24 4.14 ActivityStackSupervisor.realStartActivityLocked ................................................ 24 4.15 ActivityManagerService.startProcessLocked ....................................................... 25 5 Process类管理创建activity进程 .............................................................................................. 27

5.1 Process.start: ..................................................................................................................... 27 5.2Process.startViaZygote ................................................................................................... 28 5.3 zygoteSendArgsAndGetResult和 openZygoteSocketIfNeeded .................... 28 6 ActivityThread线程类分析 ......................................................................................................... 30

6.1 ActivityThread.main分析............................................................................................... 30

6.1.1创建了looper对象和本线程绑定。 ................................................................... 30 6.1.2创建了ActivityThread对象实例 ........................................................................ 30 6.1.3进行attach回调 ..................................................................................................... 31 6.1.4 ActivityStackSupervisor.attachApplicationLocked ................................... 34 6.1.5 ActivityStackSupervisor. ensureActivitiesVisibleLocked ......................... 34 6.2 ApplicationThread内部类 ............................................................................................. 35

6.2.1 ActivityThread.ApplicationThread. scheduleLaunchActivity ................. 35 6.2.2 ActivityThread.ApplicationThread.scheduleResumeActivity ................ 37 6.2.3 发出开机完成通知 ................................................................................................. 38

7 总结 .................................................................................................................................................. 40

7.1 luancher启动流程总结 .................................................................................................... 40 7.2 luancher黑屏问题分析 .................................................................................................... 41

1 概述:

android系统启动到zygote后,系统就真正进入java世界了;而zygote启动的第一个进程是systemserver.而用户看到的第一个程序是launcher.

本文要分析的正是从systemserver道launcher的启动流程.分析过程涉及到PowerManagerService,ActivityManagerService, PackageManagerService,

DisplayManagerService, WindowManagerService , InputManagerService ,ServiceManager等一系列相关知识,必要的地方会做一些简单分析。这些service的详细分析,在另外的笔记中再做阐述。

2 / 41

android系统启动流程

流程图:

黑线:途径1;蓝线:途径2;红线:途径3; 部分流程重叠。 显示launcher: 1)WindowManagerService setAppVisibility 2) ActivityThread . ApplicationThread Y scheduleResumeActivity scheduleResumeActivity 设置Activity resumed ActivityThread: main attach activity进程已启动 N activity resumed? N N Y do nothing return ActivityStackSupervisor: topRunningActivity==NULL? Y 1)realStartActivityLocked 2)startSpecificActivityLocked 3)attachApplicationLocked ActivityStack: resumeTopActivityLocked 4)startHomeActivity 5)resumeHomeActivity mProbeThread mProbeHandler ActivityManagerService: 1)attachApplication 2)startProcessLocked 3)startHomeActivityLocked Persistent属性 apk启动: getPersistentApplications 6)resumeTopActivitiesLocked Process: start 4)systemready startViaZygote zygoteinit(zygotesocket): runSelectLoop

systemserver: ServerThread.initAndLoop 3 / 41 android系统启动流程

2 systemserver工作内容分析

源代码路径: \\frameworks\\base\\services\\java\\com\\android\\server\\SystemServer.java systemserver最主要的作用:

1)就是初始化framework层各种service和其对应的特定servicemanager,并将他们注册到全局servicemanager类,以便其他地方只需要通过servicemanager. getService(String servicename)就可以取得该service的实例。 2)调用各service的systemready接口,启动service。 这些service基本都是单例类,所以这种注册也是方便全局调用。 下面分析其代码流程

2.1 SystemServer类简述

这里启动了ServerThread类,并调用其initAndLoop函数。

2.2 ServerThread类简述

源代码路径: \\frameworks\\base\\services\\java\\com\\android\\server\\SystemServer.java 进入同样在SystemServer.java下的ServerThread类:

4 / 41

android系统启动流程

5 / 41

android系统启动流程

可见systemsever的工作基本都是在ServerThread内完成的.

其中我们所需要关注的是ActivityManagerService,正是这个类的启动,最终完成了launcher的启动;下面接着分析ActivityManagerService在ServerThread内的5个主要步骤。

3 ActivityManagerService工作内容分析

这个分析,对应其在ServerThread内的5个步骤,重点是其如何systemReady完成launcher的启动。

从上面systemserver的分析可以看到,systemserver最后也调用了ActivityManagerService的systemReady,那么systemReady到底 是如何启动launcher的? 源代码路径:

\\frameworks\\base\\services\\java\\com\\android\\server\\am\\ActivityManagerService.java

6 / 41

android系统启动流程

3.1 ActivityManagerService之main

回顾下ActivityManagerService在systemserver中的第一个动作:

下面进入ActivityManagerService的main方法:

ActivityManagerService的main方法完成以下几个事情:

3.1.1创建ActivityManagerService实例

ActivityManagerService实例是通过AThread这个内部类创建的;这里我们看下AThread是如何创建这个实例的。

AThread是在其run方法中创建的ActivityManagerService实例,AThread. start被执行的时候,run方法就被调用,从而完成创建ActivityManagerService实例。

7 / 41

android系统启动流程

ActivityManagerService在创建了实例后,self函数就直接返回该实例:

3.1.2 创建ActivityThread实例,获取全局Context

调用ActivityThread类的systemMain创建ActivityThread实例,再调用getSystemContext获得context

\\frameworks\\base\\core\\java\\android\\app\\ActivityThread.java

这个context是ActivityThread下的全局context,所有的上下文都继承于此。

8 / 41

android系统启动流程

扩展一:为什么这里要创建一个ActivityThread线程?

ActivityThread类故名思议是处理activity生命周期内的活动的线程,

ActivityManagerService运行在systemserver进程内,为什么需要创建ActivityThread线程? 实际上systemserver.java下有一个startSystemUi,这个函数本身启动一个service处理了很多系统级的临时弹出消息,这些有一部分也处理为activity,他们的运行同样需要ActivityThread;同时其他aitivity的一些善后的工作也需要ActivityManagerService来处理;所以这个systemserver进程就需要 这么一个ActivityThread线程,换句话说,这个线程放在systemsever内创建也是可以的。ActivityManagerService实际需要的是ActivityThread下的全局conntext(即getSystemContext的结果).

扩展二: ActivityThread类是如何工作的? 这个知识点较多,放到后面再分析..

但是这里需要提前讲一下的是ActivityThread的基本原理和意义:

ActivityThread是所有应用层activity启动时所创建的进程所启动的专门管理activity生命周期事务的线程;有一个activity运行 就有一个进程,就有一个ActivityThread;

ActivityThread有一个main方法,这是app层activity创建该线程的入口,最后通过attach方法进行回调,通知上层进程和线程都创建起来了(你可以显示了)。 而ActivityManagerService是通过systemMain来创建的线程,进程则不需要创建了,因位他本来就是zygote拉起的systemserver进程的一部分。

可见,本质上是一样的,只是ActivityManagerService和app层activity创建线程的入口不同,权限不同。

以上其实就是所谓的android运行时环境,把进程的处理放在后台,普通java程序员根本不需要知道进程概念,只需要知道android环境就够了。

9 / 41

android系统启动流程

3.1.3创建ActivityStackSupervisor实例

记录到mStackSupervisor,ActivityStackSupervisor是启动launcher的直接起点,放到

后面讲.

3.1.4调用startRunning

这里的systemReady(null)不会被执行. ,这里完成初始化的参数值得注意: mTopComponent:栈顶Component为空 mTopAction:栈顶动作是: Intent.ACTION_MAIN mTopData:栈顶activity数据为空

10 / 41

android系统启动流程

3.2 ActivityManagerService之setSystemProcess

回顾下ActivityManagerService在systemserver中的第二个动作:

下面看下setSystemProcess的实现

Context.ACTIVITY_SERVICE在

\\frameworks\\base\\core\\java\\android\\content\\Context.java中的定义:

则其他地方可以通过ServiceManager.getService(\或

Context.ACTIVITY_SERVICE*/)来使用ActivityManagerService的单例mSelf。

另外framework-res.apk的包名是android,可以查看\\frameworks\\base\\core\\res\\下的Android.mk和AndroidManifest.xml。

11 / 41

android系统启动流程

3.3. ActivityManagerService之setWindowManager

回顾下ActivityManagerService在systemserver中的第4个动作: (第三个动作是installSystemProviders,偏离主题太远,跳过)

这样一来ActivityManagerService和ActivityStackSupervisor都得到了全局WindowManagerService的实例.

3.4 ActivityManagerService之systemready

回顾下ActivityManagerService在systemserver中的第5个动作:

systemready方法在ActivityManagerService的main方法中调用startRunning的时候被调用了一次,但是并没有执行,所以真正执行systemready还是要按看这里。 下面分析systemready的具体实现

12 / 41

android系统启动流程

3.4.1 启动所有Persistent属性的APK

进入\\frameworks\\base\\services\\java\\com\\android\\server\\pm\\PackageManagerService.java:

这个函数将遍历所有apk,具备Persistent属性,且当前不是安全模式启动,或者这个apk同时是system属性,就会被load加入list列表

13 / 41

android系统启动流程

回到ActivityManagerService.java看下addAppLocked如何拉起这些apk的进程:

3.4.2 启动launcher

调用mStackSupervisor.resumeTopActivitiesLocked();真正开始启动luancher. 注意如果luancher具备了persistent属性,则显然luancher的进程已经先于activity的调用被拉起来了。

这里产生了一个问题:

mStackSupervisor.resumeTopActivitiesLocked()这个动作在拉起所有persistent属性的apk之后,如果luancher也具备这个属性,是不是意味着luancher的进程一定会先于后面这个动作先启动?

答案是不一定,这里先解答一下。启动进程的startProcessLocked是通过socket通讯去通知底层zygote进程创建子进程,而这个通知发出后,该函数就直接返回了,连执行结果都不需要等待,所以下面到底何时能创建这个子进程,要看子进程有多少,排在第几位,何时socket得到响应。所以不排除,真正启动luancher进程的动作比后面这个mStackSupervisor.resumeTopActivitiesLocked要慢。

14 / 41

android系统启动流程

4 ActivityStackSupervisor启动launcher

相关源代码路径:

\\frameworks\\base\\services\\java\\com\\android\\server\\am\\ActivityStackSupervisor.java

\\frameworks\\base\\services\\java\\com\\android\\server\\am\\ ActivityStack.java

4.1首先回顾一下ActivityStackSupervisor实例的初始化

1) ActivityStackSupervisor实例构造:

systemserver调用ActivityManagerService的main,后者在最后创建了ActivityStackSupervisor实例 ActivityManagerService.main

ActivityStackSupervisor的构造函数:

这里ActivityStackSupervisor在构造时记录了ActivityManagerService创建的service实例,全局context,和looper.

2) setWindowManager设置窗口管理

systemserver自己创建了WindowManagerService实例:

systemserver调用ActivityManagerService的setWindowManager,后者则内部调用了ActivityStackSupervisor的setWindowManager ActivityManagerService. setWindowManager:

ActivityStackSupervisor. setWindowManager:

注意这里不仅仅是记录了这个全局的WindowManagerService,还创建了一个home属性的activity栈空间,mHomeStack,并加入到mStacks,但这里仅仅是mStacks这个

15 / 41

android系统启动流程

ArrayList中加入了这个数据,仅此而已。

4.2 进入ActivityStackSupervisor.resumeTopActivitiesLocked

这里最终执行的是resumeTopActivitiesLocked(null, null, null);

mStacks在setWindowManager的时候已经加入了mhomeStack,所以此时mStacks.size()为1,stack即为mHomeStack,进入分支stack.resumeTopActivityLocked(null);

4.3 进入ActivityStack.resumeTopActivityLocked

显然这时,topRunningActivityLocked一定返回null,程序回到mStackSupervisor.resumeHomeActivity(prev);prev为NULL。 注意:

这里的mStackSupervisor正是ActivityManagerService.main中初始化的

16 / 41

android系统启动流程

ActivityStackSupervisor,在ActivityStackSupervisor. setWindowManager 内部创建ActivityStack实例mHomeStack被创建的时候传进来

4.4 回到ActivityStackSupervisor.resumeHomeActivity。

mHomeStack这个空间被movetop,但是此时launcher的activity并没有运

行,.topRunningActivityLocked(null);自然还是null,mIsHomeActivityStarted为false,程序进入mProbeThread.start();。 注意:

mProbeThread是final变量,性质是线程,定义时就初始化,但是并没有start,所以mProbeThread.isAlive()必为false,mProbeThread.getState() != Thread.State.TERMINATED为true。

4.5 ActivityStackSupervisor.mProbeThread

mProbeThread为ActivityStackSupervisor的内部类,run方法给handler发出START_HOME_MSG消息。

17 / 41

android系统启动流程

4.6 ActivityStackSupervisor.mProbeHandler

mProbeHandler为私有final成员变量。他的工作只有一个就是调用ActivityServiceManger的startHomeActivityLocked,执行这一步后mIsHomeActivityStarted变为true。

特别注意:这一步是消息发送,可能存在调度问题而导致startHomeActivityLocked实际调用慢。前面已经分析过,ActivityStackSupervisor中的mService就是ActivityManagerService。

4.7 回到ActivityManagerService.startHomeActivityLocked

18 / 41

android系统启动流程

首先调用getHomeIntent构造一个intent为CATEGORY_HOME类型,

然后通过resolveActivityInfo函数向PackageManagerService查询Category类型为HOME的Activity,此时aInfo即luancher的ActivityInfo。

通过getProcessRecordLocked,进一步查询该app的执行情况,如果查不到则表明进程都没启动,如果app进程查到了但是instrumentationClass为空则表明activity未启动,此时调用mStackSupervisor.startHomeActivity(intent, aInfo);

4.8 ActivityStackSupervisor.startHomeActivity

传入startActivityLocked的参数只有intent和aInfo不为空,程序很容易判断进入 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); r正是根据intent和ainfo创建的ActivityRecord,直到这时才有了实际的Activity准备启动,但是此时还没有加入到activityStack的栈顶。

19 / 41

android系统启动流程

4.9 ActivityStackSupervisor.startActivityUncheckedLocked

这个函数很长,仔细梳理并通过加打印,确认其会进入最后ActivityStack类的的startActivityLocked,而targetStack为之前创建的homestack。

特别注意:

doResume参数为true.,

newTask为true(因为启动方式为Intent.FLAG_ACTIVITY_NEW_TASK)

20 / 41

android系统启动流程

4.10 ActivityStack.startActivityLocked

1)直到这里,launcher的activity才真正加到到activitystack的栈顶。

if (doResume) {

mStackSupervisor.resumeTopActivitiesLocked(); }

2)正常情况应该进入第二个分支的mWindowManager.addAppToken,并最后执行

注意:mWindowManager.addAppToken的调用将当前acitivity的apptoken加入到window管理里面去,后面才能把他显示出来。

21 / 41

android系统启动流程

4.11 ActivityStackSupervisor.resumeTopActivitiesLocked

和前面一样,这里传入的参数为空:

程序再回到ActivityStack. resumeTopActivityLocked。

4.12 ActivityStack.resumeTopActivityLocked

程序走到这里,才终于走到了显示出launcher的边缘。 下面的resumeTopActivityLocked需要仔细分析:

22 / 41

android系统启动流程

这个函数的层次:

1)if (next == null) {,启动home: resumeHomeActivity 2) 目标next已经是mResumedActivity,直接return

3)目标next的app和app.thread都已经建立,直接进入显示,调用mWindowManager.setAppVisibility(next.appToken, true)和

next.app.thread.scheduleResumeActivity;否则调用

mStackSupervisor.startSpecificActivityLocked(next, true, true)进入继续做其他处理..

显然此时不会走1);

如果能走2),一定是被别的地方已经调用了显示; 那么正常启动应该走3)。 对于层次3),做下分析:

如果不是persistent属性的launcher,显然从前面的分析看,一直走到这里也不会有人拉起他的进程;那么就是说正常情况下,普通不带persistent属性的launcher应该 会走到调用startSpecificActivityLocked,跟踪也多是如此。

之所以说多是如此,是因为实际上系统上还有其他方法来保证launcher这个activity进程被尽快拉起,所以有时会走到“if (next.app != null && next.app.thread != null) {”这个分支下。

问题:有没有可能走到层次2)上面去?假设有别的地方还调用了显示,何尝不会?

23 / 41

android系统启动流程

4.13 ActivityStackSupervisor.startSpecificActivityLocked

此时,如果满足条件if (app != null && app.thread != null),则会调用realStartActivityLocked。

而如果系统没有其他地方启动launcher的进程,显然就会进入mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, \

来自己拉起进程,那么这个时候,谁去显示?似乎都没人去显示launcher了?

4.14 ActivityStackSupervisor.realStartActivityLocked

24 / 41

android系统启动流程

函数里面:

调用mWindowManager.setAppVisibility(r.appToken, true);设置窗口可见; 调用app.thread.scheduleLaunchActivity启动LaunchActivity的绘制,即oncreate+onresume.

调用stack.minimalResumeActivityLocked(r);记录该app为resumed状态:

走到这里,正常的launcher启动流程就讲完了,但却留下2个问题: 问题1:

如果launcher不带persistemt属性,也没有别的地方会主动创建launcher的进程,那么startSpecificActivityLocked会走入mService.startProcessLocked,而不是realStartActivityLocked,这种情况下谁来显示? 问题2:

假设有别的地方调用了realStartActivityLocked,而这时apptoken没准备好,显然光scheduleLaunchActivity画好了ui还是显示不出来,但是这时却仍然执行了: r.state = ActivityState.RESUMED;

这个时候上面的ActivityStack.resumeTopActivityLocked就会走入层次2,什么都不做就直接return了,导致launcher不显示。

因此我们还有必要跟着mService.startProcessLocked这个分支再继续看看。

4.15 ActivityManagerService.startProcessLocked

回顾下startSpecificActivityLocked走mService.startProcessLocked的情况:

这段代码也可以看出,ProcessRecord app由startProcessLocked产生,并同时创建了一个app.thread,也就是说每创建一个进程就一定有一个thread线程,至少对于activity而言是这样。 (注意:ActivityManagerService.SystemReady里面在主动启动persistent属性的apk时,也是调用的该函数)。

继续ActivityManagerService.startProcessLocked,

25 / 41

android系统启动流程

继续进入重载的ActivityManagerService. startProcessLocked(只有3个参数)

26 / 41

android系统启动流程

这里有3个信息值得关注: 1) Process.start:

进程启动,Process是进程管理类,一直跟踪下去,会发现他最后和zygote进程启动的服务端socket进行了通讯,通知zygote分化出一个子进程来。 2) android.app.ActivityThread

Process.start的时候,传入的class名称是android.app.ActivityThread,这里就是之前说的activity的进程一定对应着一个后台activitythread进程的,activity的所有生命周期动作都是activitythread处理的,所以前面真正让activity显示的是app.thread的schedule名称的相关函数,后面再分析 3)后面的打印信息

这里专门截取这个打印信息,是为了让大家看到这种打印数据组织方式,同时知道进程创建后,android系统一定有这么一个打印,我们在看log的时候就可以关注这个信息。 搜索log的时候也注意,直接搜索整句log,在代码中是搜索不到的,因为很多地方都像上面被截断了,需要搜索单个字符串。

5 Process类管理创建activity进程

源代码路径:

\\frameworks\\base\\core\\java\\android\\os\\ Process.java

5.1 Process.start:

重点关注前4个参数,具体到我们追踪的luancher: 第一个参数: processclass,android.app.ActivityThread 第二个参数:nicename对应着进程名称launcher. 第三个参数:uid,用户id 第四个参数:gid:用户组id

27 / 41

android系统启动流程

5.2 Process.startViaZygote

5.3 zygoteSendArgsAndGetResult和 openZygoteSocketIfNeeded

28 / 41

android系统启动流程

1)openZygoteSocketIfNeeded方法: 服务端zygote这个socket的连接,

继续创建sZygoteSocket收发数据用的stream对象和buffer。 2)zygoteSendArgsAndGetResult:

完成了java层LocalSocket 的创建得到sZygoteSocket ,并继续完成和zygote进程的

利用sZygoteWriter发送创建进程需要的参数,包括进程名称nicename(即luancher),进程要启动的第一个class(android.app.ActivityThread),uid和gid等 3)底层响应

参考《android系统从init进程开始到systemserver启动详细流程.docx》的6.3.4和6.3.5 此时\\frameworks\\base\\core\\java\\com\\android\\internal\\os\\ZygoteInit.java下的 ZygoteInit .runSelectLoop()接收到socket连接请求,继续接收参数列表,开始fork子进程,并最终执行该进程的入口函数;继续进入到

\\frameworks\\base\\core\\java\\com\\android\\internal\\os\\ZygoteConnection.java的 ZygoteConnection .handleChildProc方法。

在《android系统从init进程开始到systemserver启动详细流程.docx》的6.3.5节已经分析过,ZygoteConnection .handleChildProc执行的入口函数,是app层创建进程是传递的第一个参数所代表的class的main函数,所以这里就是android.app.ActivityThread的main函数。

到此为止,luancher运行需要的子进程创建完毕,名称为launcher,第一个要执行的函数是

29 / 41

android系统启动流程

android.app.ActivityThread的main。

6 ActivityThread线程类分析

源代码路径: \\frameworks\\base\\core\\java\\android\\app\\ActivityThread.java

6.1 ActivityThread.main分析

ActivityThread这个线程是专门管理activity运行生命周期的各种动作的封装。

当然他实际还包含了对systemserver这个进程创建管理线程的工作,之前分析过其入口是systemmain,而普通的activity的入口是main;这二者本质是一样的,只是处理的权限等属性不同。

main做3个主要的任务,分析如下:

6.1.1创建了looper对象和本线程绑定。

原来我们在activity或service或dialog中可以随便使用handler是这个线程在后台付出的努力。

关于handler,looper,messagequeue之间的关系可以百度或参考《深入理解Android 卷1》,比较简单,这里不讨论。

6.1.2创建了ActivityThread对象实例

注意,当new ActivityThread()的时候,其成员变量

final ApplicationThread mAppThread = new ApplicationThread(); 同时被创建。

ApplicationThread是内部类,继承自ApplicationThreadNative

ApplicationThreadNative继承自接口IApplicationThread

30 / 41

android系统启动流程

这意味着mAppThread变量可以直接转换为IApplicationThread。

6.1.3进行attach回调

ActivityThread.attach

注意,这里正是把mAppThread转换为IApplicationThread,再调用了mgr.attachApplication(mAppThread);。

1) ActivityManagerNative. getDefault

源代码路径\\frameworks\\base\\core\\java\\android\\app\\ActivityManagerNative.java

注意,这里有2个知识点:

a) binder通讯最终调用到ActivityManagerService.attachApplication

gDefault中return的am是ActivityManagerProxy类,传入的参数b是一个binder客户端(从ServiceManager.getService(\可以知道他是

ActivityManagerService的ibinder),该参数被赋值给mRemote变量。

31 / 41

android系统启动流程

这时ActivityThread.attach实际进入ActivityManagerProxy. attachApplication

transact通讯会使得服务端ActivityManagerService执行onTransact。

而ActivityManagerService自己继承自ActivityManagerNative,也没有重载onTransact,所以这里会执行ActivityManagerNative.onTransact,进入到

调用ActivityManagerService自己的attachApplication方法。

32 / 41

android系统启动流程

b 模板类

gDefault方法返回是一个模板类Singleton:

可以看到,这个模板类的作用就是将他的模板T统统搞成单例类,以保证

ActivityManagerNative. getDefault即使被反复调用,都始终只有一个binder客户端。

2)回到ActivityManagerService. attachApplication

继续看attachApplicationLocked

33 / 41

android系统启动流程

这里有两件事要关注: 第一:

makeActive这个方法将当前thread记录到了ProcessRecord下,这就是我们之前说的ProcessRecord.thread的来源。

第二:

程序最终进入了mStackSupervisor.attachApplicationLocked,可见如果完全由调用

lucnher的流程自己来拉起他的进程的话,最后转了一圈还是回到了mStackSupervisor。 mStackSupervisor.attachApplicationLocked到底做了什么?

6.1.4 ActivityStackSupervisor.attachApplicationLocked

一目了然,这个时候会走到调用realStartActivityLocked,而这个函数在前面4.1.4分析过了,会调用ActivityThread.ApplicationThread.scheduleResumeActivity触发显示。

6.1.5 ActivityStackSupervisor. ensureActivitiesVisibleLocked

mStackSupervisor.attachApplicationLocked的else的分支,会走到ensureActivitiesVisibleLocked也需要关注:

ensureActivitiesVisibleLocked会检查当栈顶的homestack对应的activity进程没有启动的话,他也会触发调用mStackSupervisor.startSpecificActivityLocked(r, false, false);

34 / 41

android系统启动流程

这意味着:其他任何进程走到这个attach的时候,只要luancher这个activity进入栈顶了,就可能执行这个动作拉起luancher的进程。

6.2 ApplicationThread内部类

上面attach流程中回传出来的thread实际是ActivityThread. ApplicationThread转换成IApplicationThread而来的;还记得之前我们分析luancher流程时,真正luancher的resume显示是靠app.thread.scheduleLaunchActivity和

app.thread.scheduleResumeActivity。现在就来看看这两个方法到底怎么在显示; 很显然这两个方法就在ApplicationThread这个内部类里面。

进入到ApplicationThread,看到的不仅仅是这两个方法,activity生命周期相关的动作处理都在这里了: schedulePauseActivity scheduleStopActivity scheduleResumeActivity scheduleLaunchActivity scheduleRelaunchActivity scheduleDestroyActivity。 这里只看我们关注的2个方法.

6.2.1 ActivityThread.ApplicationThread. scheduleLaunchActivity

1) ApplicationThread .scheduleLaunchActivity

2) H.handleMessage :

H是ApplicationThread的一个内部类,本质是一个handler:

H.handleMessage:

35 / 41

android系统启动流程

3)ApplicationThread.handleLaunchActivity:

这里明确看到performLaunchActivity构造了一个activity实例,紧接着就调用了handleResumeActivity,到这里已经可以大胆猜测: handleResumeActivity就对应onResume,

performLaunchActivity不仅构造activity还调用onCreate,否则无法直接onResume.

4)ApplicationThread. performLaunchActivity

36 / 41

android系统启动流程

5) ApplicationThread. handleResumeActivity

6.2.2 ActivityThread.ApplicationThread.scheduleResumeActivity

1) ApplicationThread. scheduleResumeActivity

2) H.handleMessage:

同样进入了H内部H.handleMessage:

37 / 41

android系统启动流程

可以看到同样调用了handleResumeActivity。

到这里,launcher显示流程就结束了.

6.2.3 发出开机完成通知

发出开机广播:android.intent.ACTION_BOOT_COMPLETED 设置开机属性: sys.boot_completed为1

ApplicationThread. handleResumeActivity里面还有一句代码:

在当前thread的looper的消息队列中增加一个idlehandler: Idler

当该消息被发出的时候,Idler.queueIdle被调用,am.activityIdle被执行。 和前面关于attach的流程一样,这里也是一个binder通讯,这句代码最终执行到了ActivityManagerService. activityIdle:

38 / 41

android系统启动流程

继续进入到ActivityStackSupervisor.activityIdleInternalLocked

回到ActivityManagerService.finishBooting:

终于完成发出开机广播和设置开机属性为1.

39 / 41

android系统启动流程

7 总结

综合前面的分析,事实上,我们已经看到luancher的显示入口只有一个就是

ActivityThread.ApplicationThread下的各个schedule方法;但是拉起luancher进程和进入显示的过程的却有多个途径。

7.1 luancher启动流程总结

1)拉起launcher进程 途径1:

ActivityManagerService.systemready执行getPersistentApplications来主动拉起具有persistent属性的launcher. 途径2:

任何一个app进程启动,执行到ActivityStackSupervisor. attachApplicationLocked的时候,如果launcher已经进入栈顶,而当前attach回调的进程不是luancher,也会主动拉起launcher。 途径3:

launcher不具备persistent属性,也没有其他进程通过attachApplicationLocked来拉起launcher进程,则在进入ActivityStackSupervisor.startSpecificActivityLocked的流程后,拉起luancher进程

2)进入ActivityThread.ApplicationThread下的各个schedule显示的流程: 途径1:

进程并行拉起,resume launcher的流程进入ActivityStack.resumeTopActivityLocked

的if (next.app != null && next.app.thread != null) 这个分支,调用next.app.thread.scheduleResumeActivity显示 途径2:

进程并行拉起,resume launcher的流程进入ActivityStack.resumeTopActivityLocked

的if (next.app != null && next.app.thread != null) 时,进程没完全起来,条件不成立,进入mStackSupervisor.startSpecificActivityLocked---->realStartActivityLocked---> app.thread.scheduleLaunchActivity显示 途径3:

进程在attach回调的时候,activity栈顶已经准备好,直接调用ActivityStackSupervisor.realStartActivityLocked显示。

这个流程实际就是多种保险措施务必拉起launcher的进程并进行显示,但是这个流程应该存在优化的空间,如果能更直接底启动launcher,可能开机会更快。

40 / 41

android系统启动流程

7.2 luancher黑屏问题分析

当launcher具备persistent属性时,系统一开始就会拉起他;但这个并非完全是串行的,拉起进程的动作socket和zygote通讯,并不做任何等待就返回。

紧接着,开始启动调用launcher显示的动作,activity进入栈顶,会 执行将自身apptoken加入到windowmanager的动作,只有这个加进去了,activity的绘图才会被显示出来。

launcher进程起来后,开始attach回调,此时会出现一个时机问题: 1)如果这时形成栈顶activity信息和当前进程attach的进程信息一致,于是attachApplicationLocked调用realStartActivityLocked; 2)而这时如果mWindowManager.addAppToken还没完成的话,

realStartActivityLocked中的mWindowManager.setAppVisibility(r.appToken, true);就会失败。

3)realStartActivityLocked的写法是继续往下走,默认显示成功,调用scheduleLaunchActivity执行activity的create和resume动作,并调用

minimalResumeActivityLocked设置当前acitivity状态为resumed,这是实际只是绘图完成了,而windowmanger. setAppVisibility失败就类似于没有update,所以luancher不会显示。

4)调用launcher显示的流程继续走到ActivityStack .resumeTopActivityLocked.,但是此时activity的状态已经是resumed,于是什么都做不做,直接return,连这条补救的路径都没完成显示,最终导致黑屏。

简单解决该问题的办法就是在这个return之前再调用一次realStartActivityLocked。

如果launcher进程启动够快,则不会触发调用realStartActivityLocked,activity的状态就不会乱;或者launcher进程启动够慢或压根就由正常的流程自己去启动进程,则等于是个串行的流程,虽然慢,但是也不会出现状态乱。

尝试优化加快luancher显示:

是否可以在systemready函数中,直接找到launcherapk,第一个拉起他的进程,然后调用resumetopactivity,这样应该能引导luancher变成单一的流程,迅速显示。

41 / 41

android系统启动流程

7.2 luancher黑屏问题分析

当launcher具备persistent属性时,系统一开始就会拉起他;但这个并非完全是串行的,拉起进程的动作socket和zygote通讯,并不做任何等待就返回。

紧接着,开始启动调用launcher显示的动作,activity进入栈顶,会 执行将自身apptoken加入到windowmanager的动作,只有这个加进去了,activity的绘图才会被显示出来。

launcher进程起来后,开始attach回调,此时会出现一个时机问题: 1)如果这时形成栈顶activity信息和当前进程attach的进程信息一致,于是attachApplicationLocked调用realStartActivityLocked; 2)而这时如果mWindowManager.addAppToken还没完成的话,

realStartActivityLocked中的mWindowManager.setAppVisibility(r.appToken, true);就会失败。

3)realStartActivityLocked的写法是继续往下走,默认显示成功,调用scheduleLaunchActivity执行activity的create和resume动作,并调用

minimalResumeActivityLocked设置当前acitivity状态为resumed,这是实际只是绘图完成了,而windowmanger. setAppVisibility失败就类似于没有update,所以luancher不会显示。

4)调用launcher显示的流程继续走到ActivityStack .resumeTopActivityLocked.,但是此时activity的状态已经是resumed,于是什么都做不做,直接return,连这条补救的路径都没完成显示,最终导致黑屏。

简单解决该问题的办法就是在这个return之前再调用一次realStartActivityLocked。

如果launcher进程启动够快,则不会触发调用realStartActivityLocked,activity的状态就不会乱;或者launcher进程启动够慢或压根就由正常的流程自己去启动进程,则等于是个串行的流程,虽然慢,但是也不会出现状态乱。

尝试优化加快luancher显示:

是否可以在systemready函数中,直接找到launcherapk,第一个拉起他的进程,然后调用resumetopactivity,这样应该能引导luancher变成单一的流程,迅速显示。

41 / 41

本文来源:https://www.bwwdw.com/article/tfow.html

Top