Activity启动流程调用栈分析
基于Android 7.0源码分析,分析activity启动流程
涉及到的类
frameworks/base/services/core/java/com/android/server/am/
- ActivityManagerService.java
- ActivityStarter.java
- ActivityStackSupervisor.java
- ActivityStack.java
- ActivityRecord.java
- ProcessRecord.java
frameworks/base/core/java/android/app/
- IActivityManager.java
- ActivityManagerNative.java (内含AMP)
- ActivityManager.java
- IApplicationThread.java
- ApplicationThreadNative.java (内含ATP)
- ActivityThread.java (内含ApplicationThread)
- ContextImpl.java
1、启动流程调用链
Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
AMP.startActivity
AMN.onTransact
AMS.startActivity
ActivityStarter.startActivityMayWait
ActivityStarter.startActivityLocked
ActivityStarter.startActivityUnchecked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStarter是新添加的类,Google的注释明确了这个类的作用是解析Intent和flag(启动模式等参数),来决定如何启动Activity和调整任务栈。
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
Pause正在显示的Activity
ActivityStack.startPausingLocked
ApplicationThread.schedulePauseActivity
ActivityThread.H.handleMessage(PAUSE_ACTIVITY)
ActivityThread.handlePauseActivity
ActivityThread.performPauseActivity
//ActivityThread.callCallActivityOnSaveInstanceState//有需要时,SaveInstacneState会在这里调用
ActivityThread.performPauseActivityIfNeeded
Instrumentation.callActivityOnPause
Activity.performPause
Activity.onPause
ActivityStack.startPausingLocked通过mResumedActivity的IApplicationThread Binder来让流程进入当前应用的ActivityThread处理Pause操作。
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
...
ActivityRecord prev = mResumedActivity;
if (prev.app != null && prev.app.thread != null) {
try {
mService.updateUsageStats(prev, false);
//
prev.app.thread分别是ActivityRecord,ProcessRecord和IApplicationThread
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} ...
}
...
}
ApplicationThread中的方法都会通过消息转发给ActivityThread的Handler做处理。 更多关于ActivityThread的信息会在后面启动进程的时候提到。
关于onStop的执行 只要Activity完成onPause,之后下一个Activity就可以启动了,因此Activity onStop的执行放到ActivityThread的IdleHandler中,当ActivityThread的MessageQueue处理完队列中的消息后,再去执行Activity.onStop,提高应用启动的效率。
提示:完成onPause是启动下一个Activity的必要条件,因此onPause中最好不要执行耗时的操作。
调用栈如下:
MessageQueue.next//完成队列中所有消息处理后
ActivityThread.Idler.queueIdle
ActivityManagerNative.activityIdle
ActivityManagerService.activityIdle
ActivityStackSupervisor.activityIdleInternalLocked
ActivityStack.stopActivityLocked
ApplicationThread.scheduleStopActivity
ActivityThread.H.sendMessage(STOP_ACTIVITY)
ActivityThread.H.handleMessage
ActivityThread.handleStopActivity
ActivityThread.performStopActivityInner
//ActivityThread.callCallActivityOnSaveInstanceState
Activity.performStop
Activity.onStop
ActivityThread中IdleHandler的定义:
//ActivityThread.java
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
...
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (a.activity != null && !a.activity.mFinished) {
try {
//MessageQueue目前灭有待处理消息,告知ams执行idle处理
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
return false;
}
}
完成onPause是启动下一个Activity的必要条件,因此onPause中最好不要执行耗时的操作。
//activity pause完成
ActivityThread.handlePauseActivity
ActivityManagerNative.getDefault().activityPaused
ActivityManagerService.activityPaused
ActivityStack.activityPausedLocked
ActivityStack.completePauseLocked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStackSupervisor.startSpecificActivityLocked
可以注意到,ActivityStack.resumeTopActivityInnerLocked方法就是前面发起Pause Activity的地方,现在因为旧的Activity已经Paused,因此进入下一步,如果进程存在则启动Activity,否则需要新建进程。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
ProcessRecord app = null;
...
//如果进程和ApplicationThread都存在,那么直接启动Activity
if (app != null && app.thread != null) {
try {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
}
...
}
//进程不存在则需要新建
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
启动目标Activity所属的进程 如需要则启动新进程,如进程已存在,那么就不需要再重复创建了,流程上会直接进入创建Activity并执行onCreate的ActivityStackSupervisor.realStartActivityLocked方法,当中的处理也会确保Application和相关类在Activity启动前就存在。
创建进程的调用栈:
ActivityManagerService.startProcessLocked
ActivityManagerService.startProcessLocked
Process.start
Process.startViaZygote//openZygoteSocketIfNeeded获取socket读写管道
Process.zygoteSendArgsAndGetResult
ActivityManagerService向Process.start指定了要启动的Class为 "android.app.ActivityThread",因此在进程创建之后,会直接在其中执行ActivityThread.main方法
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
...
}
ActivityThread.main ActivityThread可以等同于我们常说的应用“主线程”,但ActivityThread本身并不是线程,至少它不是继承自Thread的。准确来说,应用的主线程只负责执行ActivityThread的main方法。
main方法启动了一个Looper循环,无限的等待接收外部发送过来的Message,执行对应的处理。 因此可以说Android应用完全是靠消息驱动的。
Google之所以将主线程称为UI线程,就是要想强调主线程最好只用来做UI操作,这样能避免耗时操作引发ANR。
//ActivityThread.java
public static void main(String[] args) {
...
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
前面可以看到,系统指定了Zygote在创建进程后直接执行ActivityThread.main方法,这个方法启动了一个Looper循环,因此主线程中的所有操作都会通过这个Looper来分发给ActivityThread的Handler来执行。 前面的分析也能看到,AMS能管理应用的基础就是跨进程+消息,ActivityThread的所有操作都是在主线程中执行的(包括Application和Activity的生命周期),所以说应用千万不能在主线程执行耗时操作,否则就是触发ANR。
IApplicationThread与AMS attach并创建Application 如果目标Application已经存在,那么这一节也可以忽略。
ActivityThread.main在执行looper前,先将Application binder注册给AMS,随后将完成ApplicationContext , Instrumentation , 和Application实例的创建,并执行Application的onCreate方法
ActivityThread.main
ActivityThread.attach
ActivityManagerNative.attachApplication
ActivityManagerService.attachApplication
ApplicationThread.bindApplication
ActivityThread.H.sendMessage(BIND_APPLICATION)
ActivityThread.H.handleMessage
ActivityThread.handleBindApplication
//创建AppContext,Instrumentation和Application实例,并执Application.onCreate
{ContextImpl.createAppContext -> new Instrumentation -> LoadApk.makeApplication -> Instrumentation.callApplicationOnCreate}
//完成attach
ActivityStackSupervisor.attachApplicationLocked
创建Activity并执行onCreate 完成Application attach后,ActivityStackSupervisor终于要通知ApplicationThread去启动新的Activity。过程会创建新的Activity, Context,并将一些Activity需要用到的数据和实例attach给Activity,最后由Instrumentation来调用Activity.onCreate方法
ActivityStackSupervisor.attachApplicationLocked
ActivityStackSupervisor.realStartActivityLocked
ApplicationThread.scheduleLaunchActivity
ActivityThread.H.sendMessage(LAUNCH_ACTIVITY)
ActivityThread.H.handleMessage
ActivityThread.handleLaunchActivity
ActivityThread.performLaunchActivity
//创建Activity -> 创建Context -> 将Activity与Context/app等信息关联
{createBaseContextForActivity -> Activity.attach}
Instrumentation.callActivityOnCreate
Activity.performCreate
Activity.onCreate
ActivityRecord并没有继承于Binder。 但ActivityRecord的成员变量appToken的数据类型为Token,Token继承于IApplicationToken.Stub。
appToken:system_server进程通过调用scheduleLaunchActivity()将appToken传递到App进程,
调用createActivityContext(),保存到ContextImpl.mActivityToken 调用activity.attach(),保存到Activity.mToken;
Start 和 Resume 在Activity.onCreate执行完成之后,ActivityThread.performLaunchActivity方法会继续发起Activity的onStart和onResume。
ActivityThread.performLaunchActivity
Activity.performStart
Instrumentation.callActivityOnStart
Activity.onStart
//Instrumentation.callActivityOnRestoreInstanceState //onStart结束后可能会调用OnRestoreInstanceState
//回到ActivityThread.handleLaunchActivity
ActivityThread.handleResumeActivity
ActivityThread.performResumeActivity
Activity.performResume
Instrumentation.callActivityOnResume
Activity.onResume
至此,新的Activity已经在屏幕中可见了。
小结 要点:
- ActivityManagerService是一个Binder,注册到SystemServer。
- ApplicationThread是ActivityThread的内部类,是一个实现了IActivityThread的Binder。AMS通过ApplicationThread对应用进行控制。
- onPause执行完成后,由ActivityThread的IdleHandler触发onStop的执行
- 只有目标应用的进程不存在时才会重新创建进程(Process)
参考:http://blog.csdn.net/wilschan0201/article/details/73888004