前言
源码分析基于android-26
案例
- 在MainActivity中通过startActivityForResult()方法启动AActivity
Intent intent = new Intent(MainActivity.this, AActivity.class);
startActivityForResult(intent,1);
2.AActivity启动BActivity后,finish掉
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(AActivity.this, BActivity.class);
startActivity(intent);
setResult(Activity.RESULT_OK);
finish();
}
});
3.BActivity通过back按键
讨论
这个案例和前文的案例的区别是:AActivity在启动BActivity的同时finish掉了自己。
源码
1.AActivity的finish流程如下
1.Activity#finish(DONT_FINISH_TASK_WITH_ACTIVITY)
2.ActivityManagerService#finishActivity
3.ActivityStack#requestFinishActivityLocked
4.ActivityStack#finishActivityLocked
5.ActivityStack#startPausingLocked;
6.prev.app.thread.schedulePauseActivity;
7.ActivityStack#schedulePauseTimeout
7.ActivityThread#handlePauseActivity
8.ActivityManagerService#activityPaused
9.ActivityStack#activityPausedLocked
9.ActivityStack#completePauseLocked
10.ActivityStack#finishCurrentActivityLocked
11.ActivityStackSupervisor#resumeFocusedStackTopActivityLocked;
12.ActivityStackSupervisor#resumeTopActivityUncheckedLocked;
2.在看下resumeTopActivityUncheckedLocked方法
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// Find the next top-most activity to resume in this stack that is not finishing and is
// focusable. If it is not focusable, we will fall into the case below to resume the
// top activity in the next focusable task.
// 找到顶部的Activity,此时是BActivity
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
// 省略部分代码
// If the top activity is the resumed one, nothing to do.
// mResumedActivity就是BActivity,并且其 == ActivityState.RESUMED
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// 直接return掉
return false;
}
3.可以看到resumeTopActivityInnerLocked直接return掉了
4.从BActivity点击back返回到MainActivity的逻辑和前文一致,唯一需要注意的点是:在AActivityfinish掉的时候已经为MainActivity的results进行了赋值,代码如下
ActivityStack#finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately){
// 省略部分代码..
finishActivityResultsLocked(r, resultCode, resultData);
// 省略部分代码..
}
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// send the result
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (resultTo.userId != r.userId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.userId);
}
}
if (r.info.applicationInfo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.userId);
}
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
resultData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
// Make sure this HistoryRecord is not holding on to other resources,
// because clients have remote IPC references to this object so we
// can't assume that will go away and want to avoid circular IPC refs.
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
5.BActivity开始finish时,从重新找下一个栈顶的activity,此时就是MainActivity,并执行onActivityResult和performResume方法
外传
mResumedActivity到底是啥,我们看下那边赋值的
ActivityStackSupervisor#realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig){
// 如果pause没有完成,进入下面分支,直接return
if (!allPausedActivitiesComplete()) {
// While there are activities pausing we skipping starting any new activities until
// pauses are complete. NOTE: that we also do this for activities that are starting in
// the paused state because they will first be resumed then paused on the client side.
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
"realStartActivityLocked: Skipping start of r=" + r
+ " some activities pausing...");
return false;
}
// 省略部分代码
// 启动activity
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);
if (andResume) {
// As part of the process of launching, ActivityThread also performs
// a resume.
stack.minimalResumeActivityLocked(r);
}
}
ActivityStack#setResumedActivityLocked(ActivityRecord r, String reason) {
// TODO: move mResumedActivity to stack supervisor,
// there should only be 1 global copy of resumed activity.
// 对mResumedActivity赋值
mResumedActivity = r;
// 赋值state
r.state = ActivityState.RESUMED;
mService.setResumedActivityUncheckLocked(r, reason);
final TaskRecord task = r.getTask();
task.touchActiveTime();
mRecentTasks.addLocked(task);
}
可见在pause完成后,mResumedActivity就是待启动的Activity