android应用程序启动过程
activity启动过程的调用链那么长,很多源码分析文章都是一个方法一个类地写这个链,容易忘记,那么这个启动过程中主要做了哪些重要的事?这才是重点
- 开启一个新的Activity任务栈
Android M 6.0,关于ActivityThread和ApplicationThread的解析
问题:
1.ApplicationThread在用户进程和在AMS进程分别是以什么形式出现?
2.它是如何作为用户进程的服务端的?
3.Activity的context对象是在何时被赋值的?
在这个图中,ActivityManagerService和ActivityStack位于同一个进程中,而ApplicationThread和ActivityThread位于另一个进程中。其中,ActivityManagerService是负责管理Activity的生命周期的,ActivityManagerService还借助ActivityStack是来把所有的Activity按照后进先出的顺序放在一个堆栈中;对于每一个应用程序来说,都有一个ActivityThread来表示应用程序的主进程,而每一个ActivityThread都包含有一个ApplicationThread实例,它是一个Binder对象,负责和其它进程进行通信。
简要介绍一下启动的过程:
-
Step 1. 无论是通过
Launcher
来启动Activity
,还是通过Activity
内部调用startActivity
接口来启动新的Activity
,都通过Binder
进程间通信进入到ActivityManagerService
进程中,并且调用ActivityManagerService.startActivity
接口; -
Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;
-
Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;
-
Step 4. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
-
Step 5. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,因为新的Activity就在原来的Activity所在的进程中进行启动;
-
Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;
-
Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。
这样,系统就完成了Activity的启动。
根Activity的启动过程:
当点击手机桌面App图标时,应用程序的启动流程开启
从Launcher进程进入到AMS所在进程:
image.png image.png
创建App进程
上图中,到ActivityStack调用ActivityStackSupervisor. startSpecificActivityLocked()方法时,系统已为我们点击的应用创建了一个进程。
image.png图片来自刘望舒的CSDN博客
activity的Context赋值:
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);//1
...
}
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window);
...
}
return activity;
}
而这整个过程中所涉及到的进程通信:
image
图片来自大神gityuan