0%

Android程序Activity启动流程

在学习这张之前请先学习Android IPC进程通信。
在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;
应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity,
依此类推,每一个Activity都可以在内部启动新的Activity。所以首先我们将分析第一种情况。 以下代码只看主干和重要部分,其他将省略,有兴趣自己翻源码。

1.首先查看Launcher.java(桌面)中的onClick方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void onClick(View v) {
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// Open shortcut
final Intent intent = ((ShortcutInfo) tag).intent;
int[] pos = new int[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[0], pos[1],
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
startActivitySafely(intent, tag);
} else if (tag instanceof FolderInfo) {
} else if (v == mHandleView) {
}
}


void startActivitySafely(Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
} catch (SecurityException e) {
}
}

这里将启动程序的主Activity,因为每个程序对应ActivityTask,所以设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。

2.Activity.startActivityForResul

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
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}

这里mMainThread就是程序的主线程ActivityThread,mMainThread.getApplicationThread()就是ApplicationThread,ApplicationThread其实是一个Binder,
作用是和ActivityManagerService通信。mToken是ActivityRecord,主要记录Activity信息,也是一个Binder。

3.Instrumentation.execStartActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {

}
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}

ActivityManagerNative.getDefault()获取ActivityManagerService的远程代理接口。

4. ActivityManagerProxy.startActivity,ActivityManagerProxy是ActivityManagerNative的内部类。

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
public int startActivity(IApplicationThread caller, Intent intent,
String resolvedType, Uri[] grantedUriPermissions, int grantedMode,
IBinder resultTo, String resultWho,
int requestCode, boolean onlyIfNeeded,
boolean debug) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeTypedArray(grantedUriPermissions, 0);
data.writeInt(grantedMode);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(onlyIfNeeded ? 1 : 0);
data.writeInt(debug ? 1 : 0);
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}

这里的参数比较多,我们先整理一下。从上面的调用可以知道,这里的参数resolvedType、grantedUriPermissions和resultWho均为null;参数caller为ApplicationThread类型的Binder实体;
参数resultTo为一个Binder实体(ActivityRecord)的远程接口,我们先不关注它;参数grantedMode为0,我们也先不关注它;参数requestCode为-1;参数onlyIfNeeded和debug均空false。

5.ActivityManagerService.startActivity

1
2
3
4
5
6
7
8
9
public final int startActivity(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug) {
return mMainStack.startActivityMayWait(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, null, null);
}

6.ActivityStack.startActivityMayWait

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
final int startActivityMayWait(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug, WaitResult outResult, Configuration config) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

boolean componentSpecified = intent.getComponent() != null;

// Don't modify the client's object!
intent = new Intent(intent);

// Collect information about the target of the Intent.
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
} catch (RemoteException e) {
aInfo = null;
}

synchronized (mService) {
int callingPid;
int callingUid;
if (caller == null) {
callingPid = Binder.getCallingPid();
callingUid = Binder.getCallingUid();
} else {
callingPid = callingUid = -1;
}


int res = startActivityLocked(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, callingPid, callingUid,
onlyIfNeeded, componentSpecified);


return res;
}
}

7. ActivityStack.startActivityLocked

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
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType,
Uri[] grantedUriPermissions,
int grantedMode, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, boolean onlyIfNeeded,
boolean componentSpecified) {

int err = START_SUCCESS;

ProcessRecord callerApp = null;
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 = START_PERMISSION_DENIED;
}
}

if (err == START_SUCCESS) {
Slog.i(TAG, "Starting: " + intent + " from pid "
+ (callerApp != null ? callerApp.pid : callingPid));
}

ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
int index = indexOfTokenLocked(resultTo);
if (DEBUG_RESULTS) Slog.v(
TAG, "Sending result to " + resultTo + " (index " + index + ")");
if (index >= 0) {
sourceRecord = (ActivityRecord)mHistory.get(index);
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}

int launchFlags = intent.getFlags();

if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
&& sourceRecord != null) {
// Transfer the result target from the source activity to the new
// one being started, including any failures.
if (requestCode >= 0) {
return START_FORWARD_AND_REQUEST_CONFLICT;
}
resultRecord = sourceRecord.resultTo;
resultWho = sourceRecord.resultWho;
requestCode = sourceRecord.requestCode;
sourceRecord.resultTo = null;
if (resultRecord != null) {
resultRecord.removeResultsLocked(
sourceRecord, resultWho, requestCode);
}
}

ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified);


return startActivityUncheckedLocked(r, sourceRecord,
grantedUriPermissions, grantedMode, onlyIfNeeded, true);
}

将所有的信息保存到ActivityRecord r中

8. ActivityStack.startActivityUncheckedLocked

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
final int startActivityUncheckedLocked(ActivityRecord r,
ActivityRecord sourceRecord, Uri[] grantedUriPermissions,
int grantedMode, boolean onlyIfNeeded, boolean doResume) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;

int launchFlags = intent.getFlags();

// If the caller has asked not to resume at this point, we make note
// of this in the record so that we can skip it when trying to find
// the top running activity.
if (!doResume) {
r.delayedResume = true;
}

ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
!= 0 ? r : null;


boolean addingToTask = false;
if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
(launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// If bring to front is requested, and no result is requested, and
// we can find a task that was started with this same
// component, then instead of launching bring that one to the front.
if (r.resultTo == null) {
// See if there is a task to bring to the front. If this is
// a SINGLE_INSTANCE activity, there can be one and only one
// instance of it in the history, and it is always in its own
// unique task, so we do a special search.
ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
? findTaskLocked(intent, r.info)
: findActivityLocked(intent, r.info);
if (taskTop != null) {
}
}
}

if (r.packageName != null) {
// If the activity being launched is the same as the one currently
// at the top, then we need to check if it should only be launched
// once.
ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
if (top != null && r.resultTo == null) {
if (top.realActivity.equals(r.realActivity)) {
if (top.app != null && top.app.thread != null) {
if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
// For paranoia, make sure we have correctly
// resumed the top activity.
if (doResume) {
resumeTopActivityLocked(null);
}
if (onlyIfNeeded) {
// We don't need to start a new activity, and
// the client said not to do anything if that
// is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
top.deliverNewIntentLocked(callingUid, r.intent);
return START_DELIVERED_TO_TOP;
}
}
}
}

} else {
if (r.resultTo != null) {
sendActivityResultLocked(-1,
r.resultTo, r.resultWho, r.requestCode,
Activity.RESULT_CANCELED, null);
}
return START_CLASS_NOT_FOUND;
}

boolean newTask = false;

// Should this be considered a new task?
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
// todo: should do better management of integers.
mService.mCurTask++;
if (mService.mCurTask <= 0) {
mService.mCurTask = 1;
}
r.task = new TaskRecord(mService.mCurTask, r.info, intent,
(r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+ " in new task " + r.task);
newTask = true;
if (mMainStack) {
mService.addRecentTaskLocked(r.task);
}

} else if (sourceRecord != null) {

} else {
}

logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
startActivityLocked(r, newTask, doResume);
return START_SUCCESS;
}

这里launchFlags是的启动模式,ActivityRecord taskTop 获取最顶层Activity,但是由于是新开启的程序,没有Activity,所以taskTop为null。
然后新建一个TaskRecord,TaskRecord表示Activity任务栈,然后保存到r中。TaskRecord中其实并没有包含Activity的列表,所以在查找某个Activity栈中的Activity需要遍历ActivityManagerService中的的ActivityRecord,
然后根据ActivityRecord中的TaskRecord查找同一个栈内的Activity,所以要将TaskRecord保存到r中。

9. ActivityStack.resumeTopActivityLocked

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
private final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume) {
final int NH = mHistory.size();

int addPos = -1;

if (!newTask) {
// If starting in an existing task, find where that is...
boolean startIt = true;
for (int i = NH-1; i >= 0; i--) {
ActivityRecord p = (ActivityRecord)mHistory.get(i);
if (p.finishing) {
continue;
}
if (p.task == r.task) {
// Here it is! Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.
addPos = i+1;
if (!startIt) {
mHistory.add(addPos, r);
r.inHistory = true;
r.task.numActivities++;
mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,
r.info.screenOrientation, r.fullscreen);
if (VALIDATE_TOKENS) {
mService.mWindowManager.validateAppTokens(mHistory);
}
return;
}
break;
}
if (p.fullscreen) {
startIt = false;
}
}
}

if (doResume) {
resumeTopActivityLocked(null);
}
}

10. ActivityStack.resumeTopActivityLocked

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
final boolean resumeTopActivityLocked(ActivityRecord prev) {
// Find the first activity that is not finishing.
ActivityRecord next = topRunningActivityLocked(null);

// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mUserLeaving;
mUserLeaving = false;

if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
if (mMainStack) {
return mService.startHomeActivityLocked();
}
}

next.delayedResume = false;


// We need to start pausing the current activity so the top one
// can be resumed...
if (mResumedActivity != null) {
if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
startPausingLocked(userLeaving, false);
return true;
}


return true;
}

11. ActivityStack.startPausingLocked

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
private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
if (mPausingActivity != null) {
RuntimeException e = new RuntimeException();
Slog.e(TAG, "Trying to pause when pause is already pending for "
+ mPausingActivity, e);
}
ActivityRecord prev = mResumedActivity;
if (prev == null) {
RuntimeException e = new RuntimeException();
Slog.e(TAG, "Trying to pause when nothing is resumed", e);
resumeTopActivityLocked(null);
return;
}
if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();

mService.updateCpuStats();

if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
System.identityHashCode(prev),
prev.shortComponentName);
prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
prev.configChangeFlags);
if (mMainStack) {
mService.updateUsageStats(prev, false);
}
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
}

}

prev.app.thread.schedulePauseActivity调用ApplicationThreadProxy的schedulePauseActivity方法。

12. ApplicationThreadProxy.schedulePauseActivity

1
2
3
4
5
6
7
8
9
10
11
12
 public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}

13. ApplicationThread.schedulePauseActivity, ApplicationThread是ActivityThread的内部类。

1
2
3
4
5
6
7
8
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
queueOrSendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0),
configChanges);
}

14. ActivityThread.queueOrSendMessage

1
2
3
4
5
6
7
8
9
10
11
12
13
private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
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;
mH.sendMessage(msg);
}
}

15. ActivityThread.H.handleMessage

1
2
3
4
case PAUSE_ACTIVITY:
handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
maybeSnapshot();
break;

####16. ActivityThread.handlePauseActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private final void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);
}

r.activity.mConfigChangeFlags |= configChanges;
Bundle state = performPauseActivity(token, finished, true);

// Make sure any pending writes are now committed.
QueuedWork.waitToFinish();

// Tell the activity manager we have paused.
try {
ActivityManagerNative.getDefault().activityPaused(token, state);
} catch (RemoteException ex) {
}
}
}

通过performPause将Activityactivity pause, 然后ActivityManagerNative.getDefault().activityPaused(token, state)通知ActivityManagerSerice。

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
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
if (r.paused) {
if (r.activity.mFinished) {
return null;
}
}
Bundle state = null;
if (finished) {
r.activity.mFinished = true;
}
try {
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
state = new Bundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
r.state = state;
}
// Now we are idle.
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}

} catch (SuperNotCalledException e) {

} catch (Exception e) {

}
r.paused = true;

return state;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void callActivityOnPause(Activity activity) {
activity.performPause();
}

final void performPause() {
mCalled = false;
onPause();
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}

17. ActivityManagerService.activityPaused

1
2
3
4
5
6
7
8
9
10
public final void activityPaused(IBinder token, Bundle icicle) {
// Refuse possible leaked file descriptors
if (icicle != null && icicle.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
}

final long origId = Binder.clearCallingIdentity();
mMainStack.activityPaused(token, icicle, false);
Binder.restoreCallingIdentity(origId);
}

18. MainStack.activityPaused

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(
TAG, "Activity paused: token=" + token + ", icicle=" + icicle
+ ", timeout=" + timeout);

ActivityRecord r = null;

synchronized (mService) {
int index = indexOfTokenLocked(token);
if (index >= 0) {
r = (ActivityRecord)mHistory.get(index);
if (!timeout) {

}
if (mPausingActivity == r) {
r.state = ActivityState.PAUSED;
completePauseLocked();
} else {

}
}
}
}

19. MainStack.completePauseLocked

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
private final void completePauseLocked() {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);

if (prev != null) {
if (prev.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
} else if (prev.app != null) {

if (prev.configDestroy) {
destroyActivityLocked(prev, true);
} else {
mStoppingActivities.add(prev);
}
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
prev = null;
}
mPausingActivity = null;
}

if (!mService.mSleeping && !mService.mShuttingDown) {
resumeTopActivityLocked(prev);
} else {
if (mGoingToSleep.isHeld()) {
mGoingToSleep.release();
}
if (mService.mShuttingDown) {
mService.notifyAll();
}
}

if (prev != null) {
prev.resumeKeyDispatchingLocked();
}

if (prev.app != null && prev.cpuTimeAtResume > 0

}
prev.cpuTimeAtResume = 0; // reset it
}

20. MainStack.resumeTopActivityLocked

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
final boolean resumeTopActivityLocked(ActivityRecord prev) {
// Find the first activity that is not finishing.
ActivityRecord next = topRunningActivityLocked(null);

// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mUserLeaving;
mUserLeaving = false;

if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
if (mMainStack) {
return mService.startHomeActivityLocked();
}
}

next.delayedResume = false;

// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mStoppingActivities.remove(next);
mWaitingVisibleActivities.remove(next);

if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);

// If we are currently pausing an activity, then don't do anything
// until that is done.
if (mPausingActivity != null) {
if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
return false;
}


if (next.app != null && next.app.thread != null) {


} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
mService.mWindowManager.setAppStartingWindow(
next, next.packageName, next.theme,
next.nonLocalizedLabel,
next.labelRes, next.icon, null, true);
}
if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
}
startSpecificActivityLocked(next, true, true);
}

return true;
}

因为新的程序还未开始,所以app和Thread为null,调用startSpecificActivityLocked;

21. MainStack.startSpecificActivityLocked

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
private final void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid);

if (r.launchTime == 0) {
r.launchTime = SystemClock.uptimeMillis();
if (mInitialStartTime == 0) {
mInitialStartTime = r.launchTime;
}
} else if (mInitialStartTime == 0) {
mInitialStartTime = SystemClock.uptimeMillis();
}

if (app != null && app.thread != null) {
try {
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}

// If a dead object exception was thrown -- fall through to
// restart the application.
}

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false);
}

mService就是ActivityManagerService。

22. ActivityManagerService.startProcessLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
ProcessRecord app = getProcessRecordLocked(processName, info.uid);


String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;


if (app == null) {
app = newProcessRecordLocked(null, info, processName);
mProcessNames.put(processName, info.uid, app);
} else {

}

startProcessLocked(app, hostingType, hostingNameStr);
return (app.pid != 0) ? app : null;
}

23. ActivityManagerService.startProcessLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {


try {
int uid = app.info.uid;
int[] gids = null;

int pid = Process.start("android.app.ActivityThread",
mSimpleProcessManagement ? app.processName : null, uid, uid,
gids, debugFlags, null);
BatteryStatsImpl bs = app.batteryStats.getBatteryStats();

}

这里直接实例化 android.app.ActivityThread,调用main方法。

24. 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
public static final void main(String[] args) {
SamplingProfilerIntegration.start();

Process.setArgV0("<pre-initialized>");

Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}

ActivityThread thread = new ActivityThread();
thread.attach(false);

Looper.loop();

if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}

thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
}

main中开启Handler消息循环,处理消息,然后调用thread.attach(false)。

25. ActivityThread.attach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private final void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
ViewRoot.addFirstDrawHandler(new Runnable() {
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
} else {

}
}

调用ActivityManagerProxy的attachApplication,主要是把Appliccation的远程引用传递给ActivityManagerService。

26. ActivityManagerProxy.attachApplication

1
2
3
4
5
6
7
8
9
10
11
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}

通过IPC调用ActivityManagerService的attachApplication。

27. ActivityManagerService.attachApplication

1
2
3
4
5
6
7
8
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}

28. ActivityManagerService.attachApplicationLocked

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
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;

app.thread = thread;
app.curAdj = app.setAdj = -100;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.forcingToForeground = null;
app.foregroundServices = false;
app.debugging = false;

mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List providers = normalMode ? generateApplicationProvidersLocked(app) : null;

// Remove this record from the list of starting applications.
mPersistentStartingProcesses.remove(app);
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"Attach application locked removing on hold: " + app);
mProcessesOnHold.remove(app);

boolean badApp = false;
boolean didSomething = false;

// See if the top visible activity is waiting to run in this process...
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
}
} else {
}
}

return true;
}

之前已经创建了一个ProcessRecord,这里首先通过pid将它取回来,放在app变量中,然后对app的其它成员进行初始化,最后调用mMainStack.realStartActivityLocked执行真正的Activity启动操作。
这里要启动的Activity通过调用mMainStack.topRunningActivityLocked(null)从堆栈顶端取回来,这时候在堆栈顶端的Activity就是MainActivity了。

29. mMainStack.realStartActivityLocked

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
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {

r.app = app;

if (localLOGV) Slog.v(TAG, "Launching: " + r);

int idx = app.activities.indexOf(r);
if (idx < 0) {
app.activities.add(r);
}

try {
if (app.thread == null) {
throw new RemoteException();
}
List<ResultInfo> results = null;
List<Intent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}

if (r.isHomeActivity) {
mService.mHomeProcess = app;
}
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
System.identityHashCode(r),
r.info, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward());

if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {

}

} catch (RemoteException e) {

}



return true;
}

30.ApplicationThreadProxy.scheduleLaunchActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
intent.writeToParcel(data, 0);
data.writeStrongBinder(token);
data.writeInt(ident);
info.writeToParcel(data, 0);
data.writeBundle(state);
data.writeTypedList(pendingResults);
data.writeTypedList(pendingNewIntents);
data.writeInt(notResumed ? 1 : 0);
data.writeInt(isForward ? 1 : 0);
mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}

31. ApplicationThread.scheduleLaunchActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
ActivityClientRecord r = new ActivityClientRecord();

r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.state = state;

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

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

queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}

32. ActivityThread.queueOrSendMessage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private final void queueOrSendMessage(int what, Object obj) {
queueOrSendMessage(what, obj, 0, 0);
}

private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
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;
mH.sendMessage(msg);
}
}

33. ActivityThread.H.handleMessage

1
2
3
4
5
6
7
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo);
handleLaunchActivity(r, null);
} break;

34. ActivityThread.handleLaunchActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
are back active so skip it.
unscheduleGcIdler();

Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
}else {
}
}

35. ActivityThread.performLaunchActivity

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
private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo,
Context.CONTEXT_INCLUDE_CODE);
}

Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {

}

try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

if (activity != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstance,
r.lastNonConfigurationChildInstances, config);

if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstance = null;
r.lastNonConfigurationChildInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}

activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;

mActivities.put(r.token, r);

} catch (SuperNotCalledException e) {

} catch (Exception e) {

}

return activity;
}

这里主要通过反射实例化Activity,然后初始化Activity中的数据,最后调用Activity的生命周期方法,到此基本结束所以流程。