关于Activity的启动流程详细说明的文章已经多如牛毛,而且流程中经常会出现超长的方法,实在没有必要再每个方法代码都罗列一次,这里只做调用栈的记录,从宏观上理解这个过程。
启动一个Activity,涉及到的相关类大概有这些(AMS范围):
下面分析从Activity调用startActivity开始,直到新Activity进入onResume的流程。
(可以通过文章目录大致了解整个过程。)
ActivityManagerService
ActivityManagerService
后面简称AMS,是用于应用管理和调度的系统服务。
在开机后,SystemServer
会自动调用ActivityManagerService.setSystemProcess
方法将AMS注册为系统服务:
//ActivityManagerService.java
public void setSystemProcess() {
...
//Context.ACTIVITY_SERVICE = "activity"
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
...
}
AMS继承自ActivityManagerNative
,即为Binder
的子类,并实现了IActivityManager
接口。IActivityManager
接口定义了给Client端调用的方法。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
ActivityManagerNative本身是单例模式的,因此系统中只会有一个ActivityManagerService实例。
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
...
private static final Singleton<IActivityManager> gDefault =
new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
...
}
ApplicationThread
每个应用(Application)都需要与系统打交道,最直接的就是跟ams打交道。因此,作为应用的主入口,ActivityThread
实现了一个Binder
内部类——ApplicationThread
,用于和系统进程交互。
private class ApplicationThread extends ApplicationThreadNative
ApplicationThreadNative
继承自Binder
,实现了IApplicationThread
接口。IApplicationThread定义了许多与应用生命周期有关的方法。
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread
分析Activity的启动流程
startActivity
在一个Activity要跳转到另外一个Activity时,常用的方法是调用startActivity方法,传入存有目标Activity信息的Intent,然后具体的操作会交给AMS来处理。
下面来看下从Activity到AMS期间的调用路径:
Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
ActivityManagerNative.getDefault().startActivity
直接来看Instrumentation.execStartActivity
,此方法通过调用ActivityManagerNative.getDefault()
获取AMS binder实例,然后调用AMS的startActivity
方法,传入当前的IApplicationThread实例和Intent等内容:
//Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManagerNative.getDefault()
方法通过ServiceManager.getService("activity")
获取AMS Ibinder实例。
//ActivityManagerNative.java
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
ActivityManagerService.startActivity
流程进入AMS,接下来的部分调用栈如下:
ActivityManagerService.startActivity
ActivityManagerService.startActivityAsUser
ActivityStarter.startActivityMayWait
ActivityStarter.startActivityLocked
ActivityStarter.startActivityUnchecked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStarter是新添加的类,Google的注释明确了这个类的作用是解析Intent和flag(启动模式等参数),来决定如何启动Activity和调整任务栈。
/**
* Controller for interpreting how and then launching activities.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
ActivityStack.resumeTopActivityInnerLocked
判断如果当前有正在显示的Activity,则需要先停止,发起Pause流程。
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 Paused执行完成后
//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
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已经在屏幕中可见了。
小结
要点:
1. ActivityManagerService是一个Binder,注册到SystemServer。
2. ApplicationThread是ActivityThread的内部类,是一个实现了IActivityThread的Binder。AMS通过ApplicationThread对应用进行控制。
3. onPause执行完成后,由ActivityThread的IdleHandler触发onStop的执行
4. 只有目标应用的进程不存在时才会重新创建进程(Process)
大致的流程已经列在目录中,就不再废话了。
整个流程看下来,可以发掘出进程,ActivityThread,Activity和AMS关系,大致如下:
这里只粗略地列出了一种启动Activity的流程,忽略的信息较多,启动模式和flag对任务栈的影响,甚至也没有提到任务栈,希望后面有时间再来分析总结。
AMS流程很多,代码架构也很庞大,要一下子读懂真的很困难,希望先将重要的流程各个击破,再反过来理解整个架构的思路。