Activity启动过程

下列源码分析是基于 Android 8.0源码

Activity的启动过程分为两种:

  • 根Activity的启动过程 - 指代根Actiivty的启动过程也可以认为是应用程序的启动过程
  • 普通Activity的启动过程 - 除启动应用程序启动的第一个Activity之外Activity的启动过程

根Activity启动过程

根Activity启动过程-冷启动

点击桌面的应用程序图标就是启动根Activity的入口,当我们点击某个应用程序图标时,就会通过Launcher请求AMS来启动该应用程序。

其中涉及了三个进程间的通信:Launcher组件AMSActivity组件

Launcher请求AMS过程

当我们在应用程序启动器Launcher上点击一个应用的图标时,Launcher组件就会调用startActivitySafely()启动该App的根Activity。

配置根Activity,需要在AndroidManifest.xml中配置 相关属性

1
2
3
4
5
6
7
8
9
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Launcher组件中startActivitySafely()相关操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// packages/apps/Launcher3/src/com/android/Launcher3/Launcher.java
public boolean startActivitySafely(View v,Intent intent,ItemInfo item){
...

intent.addFlags(Intent.FFLAG_ACTIVITY_NEW_TASK);
try{
if(Utilities.ATLEAST_MARSHMELLOW
&&(item instanceof ShortcutInfo)
&&(item.itemType == Favorites.ITEM_TYPE_SHORTCUT
||item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((ShortcutInfo)item).isPromise()){
startShortcutIntentSafely(intent,optsBundle,item);
} else if(user ==null || user.equals(Process.myUserHandle())){
startActivity(intent,optsBundle);
} else{
LauncherAppsCompat.getInstance(this).startActivityForProfile(intent.getComponent(),
user,intent.getSourceBounds(),optsBundle);
}
return true;
}catch(ActivityNotFoundException|SecurityException e){
...
}
return false;
}

设置启动Acticvity为FLAG_ACTIVITY_NEW_TASK保证根Activity在一个新任务栈中启动。Launcher.java继承了Activity接下来就到了Acticvity.startActivity()

1
2
3
4
5
6
7
8
9
// ../android/app/Activity.java
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}

接下来会走到startActivityFroResult(),第二个参数设为-1表明Launcher不需要知道返回结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ../android/app/Activity.java
Activity mParent;

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)
{
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this,
mMainThread.getApplicationThread(), /*ApplicationThread*/
mToken,
this,
intent, requestCode, options);
...
}else{
...
}
...
}

mParent代表当前Activity的父类,由于根Activity还未创建出来,所以mParent==null成立。后续向下走就会调用到Instrumentation.execStartActivity()去继续启动Activity组件。

Instrumentation用于监控应用程序和系统间的交互。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ../android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options)
{
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//检查启动Activity是否存在
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

ActivityManager.getService()用于获取AMS的代理对象。实质上是把启动过程转移到了AMS上去执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// ../android/app/ActivityManager.java
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

//../android/util/Singleton.java
public abstract class Singleton<T> {
private T mInstance;

protected abstract T create();

public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}

第一次调用到getService()时,就会调用到IActivityManagerSingleton.get(),由源码可知,该类是一个单例类。

在其中先去获取名为activity的一个代理对象(IBinder),后续实现利用了AIDL,根据asInterface()可以获得IActivityManager对象,他是AMS在本地的代理对象。然后就可以直接调用到AMSstartActivity()

Launcher请求AMS时序图

总结:

  • 用户点击桌面图标触发startActivitySafely()开始调用打开根Activity流程。
  • Launcher组件会调用到Activity.startActivity()后调用到Activity.startActivityForResult()
  • 由于从Launcher启动,根Activity尚未建立,就会走到Instrumentation.execStartActivity()
  • Instrumentation.execStartActivity()中,实际调用的是ActivityManager.getService()去继续启动Activity
  • 跟踪到ActivityManager.getService()实际返回的是一个AMS的本地代理对象IActivityManager,由前面学到的Binder机制中,这个代理对象是可以直接调用到AMS中的方法,所以execStartActivity()最终指向的是AMS.startActivity()

AMS到ApplicationThread的调用过程

Launcher请求到AMS后,后续逻辑由AMS继续执行。继续执行的是AMS.startActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// ../core/java/com/android/server/am/ActivityManagerService.java
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions)
{
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId()/*获取调用者的UserId*/);
}

//检测调用是否合法
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId)
{
//判断调用者进程是否被隔离
enforceNotIsolatedCaller("startActivity");
//检测调用者权限
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}

void enforceNotIsolatedCaller(String caller) {
if (UserHandle.isIsolated(Binder.getCallingUid())) {
throw new SecurityException("Isolated process not allowed to call " + caller);
}
}

进入到AMS.startActivity()中,会调用到startActivityAsUser(),在这个方法中需要去判断调用是否合法。需要先检测调用者进程是否被隔离以及调用者权限是否正确

前面都通过的话,就会调用到ActivityStarter.startActivityMayWait()。没有通过校验的话就会抛出SecurityException异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// ../core/java/com/android/server/am/ActivityStarter.java
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask/*Activity所在任务栈*/, String reason/*启动理由*/)
{
...
//指向 startActivityLocked 方法
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask, reason);
...

}

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask, String reason)
{
//判断启动理由不可为空
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
//指向 startActivity 方法
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);

if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
return mLastStartActivityResult;
}

ActivityStarter是Android7.0新加入的类,他是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stark相关联。

调用startActivityLocked()之后继续走向ActivityStarter.startActivity()过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask)
{
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
ProcessRecord callerApp = null;
//这个caller是一直从Launcher启动时就传下来的
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...

ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
...
doPendingActivityLaunchesLocked(false);
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}

第16行代码 caller!=null 这个caller对象是从Launcher启动时就一直传递下来的,指向的是Launcher所在的应用程序进程的ApplicationThread对象

第17行代码 mService.getRecordForAppLocked(caller) 得到的就是一个ProgreeRecord对象(用于描述一个应用程序进程)。该对象指的就是 Launcher组件所运行的应用程序进程

第30行代码 new ActivityRecord() ActivityRecord用来记录一个Activity的所有信息。在这里ActivityRecord指的就是将要启动的Activity即根Activity。

第39行代码 继续调用startActivity()并传递当前记录的Activity信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity)
{
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
}


postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
mTargetStack);

return result;
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity)
{
...
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
//如果是使用 singleTask模式启动 会新建一个任务栈用来存储Activity
newTask = true;
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}

...
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mWindowManager.executeAppTransition();
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
...
}

第30行代码 由于我们从Launcher启动根Activity时,设置启动标志为FLAG_ACTIVITY_NEW_TASK,所以就会走到setTaskFromReuseOrCreateNewTask(),这个方法主要是管理任务栈,如果没有就会创建一个新的任务栈。

第62代码 最终调用ActivityStackSupervisor.resumeDocusedStackTopActivityLocked()继续启动Activity的流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ../core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)
{
//判断当前的任务栈是否相同
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
//获取要启动Activity的所在栈的栈顶Activity且不处于停止状态
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
//由于Activity尚未启动 满足要求
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}

由于要启动的Activity尚未启动,所以会继续调用ActivityStack.resumeTopActivityUncheckedLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ../core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}

boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
mStackSupervisor.checkReadyForSleepLocked();

return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
//需要启动Activity
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// ../core/java/com/android/server/am/ActivityStackSupervisor.java


void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig)
{
// 获取即将启动Activity所在的应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);

r.getStack().setLaunchTime(r);

if (app != null && app.thread != null) {
//进程已经启动
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
//启动应用进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}

AMS-应用程序进程通信

这一节主要是从ActivityManagerService经过层层调用到达ApplicationThread的Activity启动方法。

AMS-ApplicationThread调用过程

ActivityStack:Activity的任务栈,从中获取需要进行操作的ActivityRecord进行操作。在启动过程中,它的作用是检测当前栈顶Activity是否为要启动的Activity,不是就启动新Activity,是的话就重启,在这之前需要标记一下前Activity处于Pause状态。

ActivityStackSupervisor:管理整个手机任务栈,管理着所有的ActivityStack在启动过程,它负责检查是否已有对应的应用进程在运行,如果有就直接启动Actiivty,没有的话则需新建一个应用进程。

总结:

  • 调用AMS.startActivity()实质调用其内部的startActivityAsUser()并在方法内部进行验证,判定调用者进程是否隔离以及调用者权限是否正确
  • 通过验证后,就到了ActivityStarter.startActivityMayWait(),并设置启动理由为startActivityAsUser
  • 向下调用到了startActivityLocked(),方法内部会去判定reason是否为空
  • 不为空则走到startActivity(),该方法中主要caller(指向Launcher组件所运行的进程的ApplicationThread对象)callerApp(指向Launcher组件所允许的应用程序进程),基于callerApp生成对应的ActivityRecord(记录即将要启动的Activity)并存入Activityrecord[]中备用。
  • 对应参数传入startActivity()的重载函数中,向下继续调用startActivityUnchecked()
  • startActivityUnchecked()主要是 创建新的TaskRecord(记录任务栈信息)
  • 向下切换到ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(),这个方法主要实现的是寻找需要回复的栈顶Activity
  • 内部实现由ActivityStack.resumeTopActivityUncheckedLocked()实现,这里又继续调用到resumeTopActivityInnerLocked()
  • 后续又切换回到ActivityStackSupervisor.startSpecificActivityLocked(),在该方法中获取即将启动的Activity所在应用程序进程,已启动的话调用realStartActivityLocked(),未启动的话就调用startProcessLocked()去启动进程

AMS启动应用进程

由于启动是根Activity,这时应用进程尚未启动,需要通过AMS.startProcessLocked()创建一个应用程序进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// ../core/java/com/android/server/am/ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge)
{
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler)
{
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
...
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
}


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";

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, entryPointArgs);
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
...
}

调用到Process的静态成员函数start()启动一个新的应用进程,指定了该进程的入口函数为ActivityThread.main();因此创建应用进程结束时,逻辑就转移到了ActivityThread.main()上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Process.start() => ZygoteProcess.start() == LocalSocket连接 => ZygoteServer.runSelectLoop() => ZygoteConnection.processOneCommand() => 
// 源码路径:java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
//从Zygote孵化一个新进程并赋予 pid
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);

try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();

zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;

return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}

=> ZygoteConnection.handleChildProc()

private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote)
{
...
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}

=> ZygoteInit.zygoteInit()

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();

RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();

return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

=> RuntimeInit.applicationInit()

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader)
{
...
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}

=> RuntimeInit.findStaticMain()//此时完成了对 android.app.ActivityThread.main()的反射调用

protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader)
{
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}

Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
...
}

拓展:为什么不用Binder而是采用Socket进行 ZygoteProcess与AMS间的通信。

  1. 父进程binder线程有锁,然后子进程的主线程一直在等其子线程(从父进程拷贝过来的子进程)的资源,但是其实父进程的子进程并没有被拷贝过来,造成死锁,所以fork不允许存在多线程。而非常巧的是Binder通讯偏偏就是多线程,所以干脆父进程(Zgote)这个时候就不使用binder线程
  2. fork()不支持多线程,可能导致binder调用的时候,多个service发起fork请求,导致部分service创建失败

Zygote进程孵化出新的应用进程后,通过反射执行ActivityThread.main(),在该方法中会事先准备好Looper以及MessageQueue,继续调用attach()用进程绑定到AMS,然后开始消息循环,不断读取队列消息,并分发消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// ../android/app/ActivityThread.java
2public static void main(String[] args) {
//准备主线程Looper 以便Handler调用
Looper.prepareMainLooper();
//创建主进程的 ActivityThread
ActivityThread thread = new ActivityThread();
//将该进程进行绑定
thread.attach(false);

if (sMainThreadHandler == null) {
//保存进程对应的主线程Handler
sMainThreadHandler = thread.getHandler();
}

// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//主线程开始消息循环
Looper.loop();

}
final ApplicationThread mAppThread = new ApplicationThread();
private void attach(boolean system) {
...
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}else{
...
}
...
}

AMSattach的是ActivityThread的代理对象ApplicationThread,然后AMS就可以通过代理对象对主线程进行操作。

至此,应用进程创建完毕,并且已建立主线程完毕并开启了消息循环。

创建并绑定Application

这时应用进程以及主线程已经创造完毕,接下来就是要创建Application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// ../core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
//获取当前进程的id
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid)
{

ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
// 如果获取进程信息为空 直接杀死进程并退出
if (app == null) {
if (pid > 0 && pid != MY_PID) {
killProcessQuiet(pid);
} else {
try {
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
//创建死亡代理,被kill后可以通知AMS
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}

try {
...
if (app.instr != null) {
//绑定Application
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
}catch(Exception e){
...
//启动失败 重启当前进程
startProcessLocked(app, "bind fail", processName);
return false;
}
//准备启动根Activity
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}

//绑定Service以及BroadCast的Application
...
if (badApp) {
//如果以上组件启动出错,则需要杀死进程并移除记录
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}

//如果以上没有启动任何组件,那么didSomething为false
if (!didSomething) {
//调整进程的oom_adj值, oom_adj相当于一种优先级
//如果应用进程没有运行任何组件,那么当内存出现不足时,该进程是最先被系统“杀死”
updateOomAdjLocked();
}
return true;

}

AMS.attachApplicationLocked()主要做了两步:

thread.bindApplication():绑定Application到ActivityThread上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// ../android/app/ActivityThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial)
{

if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}

setCoreSettings(coreSettings);

AppBindData data = new AppBindData();
//设置Data参数
...
sendMessage(H.BIND_APPLICATION, data);
}

private class H extends Handler {
public static final int BIND_APPLICATION = 110;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
...
}

H相当于ApplcationThreadActivityThread的中间人,其中AMS与ActivityThread通信靠 ApplicationThread,ActivityThread与ApplicationThread通信靠Handler

这里涉及的就是Android的主线程消息循环模型

ApplicationThread发送BIND_APPLICATION标识的消息时,H接收到消息,调用handleBindApplication()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Instrumentation mInstrumentation;
private void handleBindApplication(AppBindData data) {
...
//获取LoaderApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
//创建进程对应的Android运行环境ContextImpl
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

final InstrumentationInfo ii;
if (ii != null) {
...
}else{
//Activity中所有的生命周期方法都会被Instrumentation监控
//只要是执行Activity生命周期的相关方法前后一定会调用Instrumentation相关方法
mInstrumentation = new Instrumentation();
}

try {
//准备创建Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
//加载对应进程中的ContentProvider
installContentProviders(app, data.providers);
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}

try {
//调用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}

handleBindApplicaiton()主要是为了让一个Java的进程可以加入到Android中

主要执行步骤有以下几步:

  1. 设置进程的基本参数,例如进程名,时区等,配置资源以及兼容性设计。
  2. 创建进程对应的ContextImpl、LoaderApk以及Application对象,并初始化ContentProvide以及Application
  3. 创建Instrumentation监听Activity的生命周期。(一个进程对应一个Instrumentation实例)

mStackSuperVisor.attachApplicationLocked():启动根Activity

在该方法中Application已经绑定到进程上,接下来就是启动根Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// ../core/java/com/android/server/am/ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
//ActivityStackSupervisor里面 维护者所有ActiivtyStack
//通过循环 找到前台任务栈顶端的Activity
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked();
if (hr != null) {
//前台待启动的Activity与当前新建的进程一致时,启动这个Actiivty
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}

需要启动的Activity所在进程已经启动时,开始准备启动根Activity realStartActivityLocked()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig)
throws RemoteException
{
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
}

这里的app.thread的类型为IApplicationThread,它的实现是ActivityThread的内部类ApplicationThreadapp指代的是要启动的Acttvity所在的应用进程。因此这段代码指的就是要在目标应用程序进程中启动Activity。

AMS启动进程并绑定Application

ActivityThread启动Activity过程

这时Activity的启动过程从AMS切换到了ApplicationThread中,最后是调用到了ApplicationThread.scheduleLaunchActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// ../android/app/ActivityThread.java        
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo)
{

updateProcessState(procState, false);

ActivityClientRecord r = new ActivityClientRecord();

r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;

r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed;
r.isForward = isForward;

r.profilerInfo = profilerInfo;

r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r);
}

将需要启动Activity的参数封装成ActivityClientRecord,在调用sendMessage()设置类型为LAUNCH_ACTIVITY,并将ActivityClientRecord传递过去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
final H mh = new H();
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}

这里的mh指的就是H,这个HActivityThread的内部类并继承自Handler,是主线程的消息管理类。因为ApplicationThread是一个Binder,它的调用逻辑是在Binder线程池中。所以这里就要把执行逻辑切换到主线程中,就使用了Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
//将传递过来的msg.obj转化为ActivityClientRecord
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
// 获得LoaderApk类型的对象并赋值到ActivityClientRecoed中
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
...
}

每一个Android程序都是打包在一个Apk文件中的,一个Apk文件包含了一个Android程序中的所有资源。应用程序进程在启动一个Activity组件时,需要将它所属的Apk文件加载进来,以便访问内部资源。ActivityThread内部使用LoaderApk描述一个已加载的Apk文件。

继续向下调用到handleLauncheActivity()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
//Window开始初始化
WindowManagerGlobal.initialize();
//准备启动Activity
Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//将要启动的Activity状态设为 Resumed 标记待激活
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
//停止Activity启动
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}

首先调用performLaunchActivity()开始准备启动Activity,内部会调用Activity的Oncreate(),onStart(),onRestoreInstaceState()

performResumeActivity()对应生命周期的onResume(),之后开始调用View的绘制,Activity的内容开始渲染到Window上面,直到我们看见绘制结果。

1
2
3
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
}

performLaunchActivity()主要完成了如下几件事:

  1. ActivityClientRecord中获取待启动的Activity的组件信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
    //获取LoadedApk对象
    r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
    Context.CONTEXT_INCLUDE_CODE);
    }
    //获取组件信息
    ComponentName component = r.intent.getComponent();
    if (component == null) {
    component = r.intent.resolveActivity(
    mInitialApplication.getPackageManager());
    r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) {
    component = new ComponentName(r.activityInfo.packageName,
    r.activityInfo.targetActivity);
    }

    ComponentName包含了Activity组件的包名及类名。

  2. 通过Instrumentation.newActivity()使用类加载器创建Activity对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Activity activity = null;
    try {
    java.lang.ClassLoader cl = appContext.getClassLoader();
    //用类加载器创建该Activity的实例
    activity = mInstrumentation.newActivity(
    cl, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(cl);
    r.intent.prepareToEnterProcess();
    if (r.state != null) {
    r.state.setClassLoader(cl);
    }
    } catch (Exception e) {
    ...
    }
    1
    2
    3
    4
    5
    6
    7
    // ../android/app/Instrumentation.java   
    public Activity newActivity(ClassLoader cl, String className,
    Intent intent)

    throws InstantiationException, IllegalAccessException,
    ClassNotFoundException
    {
    return (Activity)cl.loadClass(className).newInstance();
    }
  3. 通过LoadedApk.makeApplication()创建Application对象(实际是判空

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

    // ../android/app/LoaderApk.java
    public Application makeApplication(boolean forceDefaultAppClass,
    Instrumentation instrumentation)
    {
    if (mApplication != null) {
    return mApplication;
    }

    //新建Application
    try {
    java.lang.ClassLoader cl = getClassLoader();
    if (!mPackageName.equals("android")) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
    "initializeJavaContextClassLoader");
    initializeJavaContextClassLoader();
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(
    cl, appClass, appContext);
    appContext.setOuterContext(app);
    } catch (Exception e) {
    if (!mActivityThread.mInstrumentation.onException(app, e)) {
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    throw new RuntimeException(
    "Unable to instantiate application " + appClass
    + ": " + e.toString(), e);
    }
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;
    }

    由于在前面创建并绑定Application过程中的bindApplication()就已经创建好了Application,所以这一步只是起到了预防作用,并且不会重复创建。

  4. 创建ContextImpl对象,并通过Activity.attach()完成一些重要数据的初始化

    1
    2
    3
    4
    5
    6
    ContextImpl appContext = createBaseContextForActivity(r);
    appContext.setOuterContext(activity);
    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, r.configCallback);

    ContextImpl是一个很重要的数据结构,它是Context的具体实现,Context中大部分逻辑都是由ContextImpl完成的。ContextImpl是通过Activity.attach()与Activity进行关联的。除此之外,在attach()中,Activity还会完成Window的创建并建立关联,这样当Window接收到外部输入事件以后就可以将事件传递给Activity。

  5. 调用Activity.oncreate()加载用户界面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    mInstrumentation.callActivityOnCreate(activity, r.state);

    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
    r.persistentState);

    mInstrumentation.callActivityOnPostCreate(activity, r.state,
    r.persistentState);

    // ../android/app/Instrumentation.java
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
    }

    // ../android/app/Activity.java
    final void performCreate(Bundle icicle) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
    }

    最终调用到Activity.performCreate()后续调用到Activity.onCreate()这时根Activity就启动了,完成了整个启动流程。

ActivityThread启动Activity过程

根Activity启动过程中涉及的进程

根Activity启动过程中涉及四个进程:Zygote进程、Launcher进程、AMS所在进程(System Server进程),应用程序进程。

根启动Activity过程中的进程切换

首先Launcher进程会向AMS发起创建根Activity请求AMS会判断根Activity所需的应用程序进程是否存在并处于启动状态

  • 未启动:请求Zygote进程创建应用程序进程
  • 已启动AMS直接启动Activity

总结

经过上述章节的描述,可以基本厘清根Activity的启动过程

当我们按下桌面上的应用程序快捷启动方式时,Launcher会调用Activity.startActivity()并设置启动FLAG为FLAG_ACTIVITY_NEW_TASK给根Activity设置任务栈,实质上是调用Instrumentation.execStartActivity()尝试启动Activity,这是一个跨进程的过程,利用IActivityManagerAMS进行通信。

AMS就会记录下要启动的Activity信息,并且跨进程通知Launcher进入pause状态,Launcher进入pause状态后,跨进程通知AMS自己已被pauseAMS会回调用自身的startActivty()去继续启动根Activity,这一步需要校验(调用者是否有权限调用),检验通过后,发现此时应用进程尚未启动,AMS就会启动新的进程,并且在新进程中创建ActivityThread对象并执行main()进程初始化。

应用进程启动完毕后,AMS通知主线程绑定Application并启动根Activity。这时AMS会通过ApplicationThread回调到我们的进程,这一步也是一个跨进程的过程,利用ApplicationThread这个Binder对象。由于回调逻辑是在Binder线程池中进行的,所以需要通过Handler H将其切回主线程,发出的消息是LAUNCH_ACTIVITY,对应调用handleLaunchActivity,在这个方法中完成了根Activity的创建以及启动。接着在handleResumeActivity()中开始Activity的内容绘制,直到绘制完成被我们看见。

普通Activity启动过程

普通Activity启动过程

普通Activity启动过程相比于根Activity启动过程,只保留了两步:AMS到Application的调用过程,ActivityThread启动Activity过程

涉及的进程也只剩:AMS所在进程(System Server进程),应用程序进程

相同进程的启动过程

例如LoadingActivity -> MainActivity

  1. LoadingActivity组件会向AMS发送一个启动MainActivity的请求,其实就是内部通过Instrumentation尝试启动Activity(execStartActivity),这是一个跨进程过程,会调用AMSstartActivity()
  2. AMS会保存下来MainActivity的组件信息,然后向LoadingActivity发送一个进入中止状态的进程间通信请求。这也就是为什么老Activity的onPause()会执行在新Activity的启动之前的原因。
  3. LoadingActivity进入中止状态后会通知到AMS继续向下执行MainActivity的启动,由于发现应用进程已经存在,所以AMS直接通过ApplicationThread回调到应用进程,这也是一个跨进程过程。
  4. 由于ApplicationThread是一个Binder对象,回调逻辑在Binder线程池中完成,需要通过Handler H切回到主线程,并发出LAUNCH_ACTIVITY消息,对应调用handleLaunchActivity
  5. 继续向下完成MainActivity的创建和启动,然后在handleResumeActivity()中完成View的绘制,直到绘制完成展示在用户面前结束。

新进程的启动过程

例如LoadingActivity -> MainActivity设置了android:process=":remote"

类似根Activity的启动过程,不过起始点是从LoadingActivity开始

  1. LoadingActivity组件会向AMS发送一个启动MainActivity的请求,其实就是内部通过Instrumentation尝试启动Activity(execStartActivity),这是一个跨进程过程,会调用AMSstartActivity()
  2. AMS会保存下来MainActivity的组件信息,然后向LoadingActivity发送一个进入中止状态的进程间通信请求。这也就是为什么老Activity的onPause()会执行在新Activity的启动之前的原因。
  3. LoadingActivity进入中止状态后会通知到AMS继续向下执行MainActivity的启动,此时发现用来运行的:remote进程不存在,就会调用AMS去启动新的应用进程,并且在新进程中创建ActrivityThread(*主进程*)并执行main()进行初始化。
  4. 应用进程启动完毕之后,向AMS发送一个启动完成的请求,AMS就会通知主线程ActivityThread去创建并绑定Application,绑定完成后,通知AMS绑定完成。AMS直接通过ApplicationThread回调到应用进程,这也是一个跨进程过程。
  5. 由于ApplicationThread是一个Binder对象,回调逻辑在Binder线程池中完成,需要通过Handler H切回到主线程,并发出LAUNCH_ACTIVITY消息,对应调用handleLaunchActivity

临时记录:

Andorid 9.0 源码添加了Sleeping状态,功能类似Stop

handleSleeping() 可能导致 onSaveInstanceState()存储异常


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!