AMS源码分析--FLAG_ACTIVITY_FORWARD_RESULT

933 阅读3分钟

前言

源码分析基于android-26

在阅读Activity启动源码的过程中发现了一个有意思flag:Intent.FLAG_ACTIVITY_FORWARD_RESULT。

不清楚的可以百度下,简单来说就是:三个Activity:MainActivity,AActivity,BActivity。其中AActivity仅仅作为过渡页面,MainActivity直接获取到BActivity中setResult设置的结果(执行MainActivity的onActivityResult方法)。

PS:是不是和《案例看源码--finish()源码分析2》很相似,唯一的区别上一节AActivity在启动BActivity的同时设置了返回结果。

案例相关代码

  1. MainActivity.java
findViewById(R.id.jump_jump).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, AActivity.class);
        startActivityForResult(intent,1);

    }
});
  1. AActivity.java
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(AActivity.this, BActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        startActivity(intent);
        finish();
    }
});
  1. BActivity.java
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        setResult(Activity.RESULT_OK);
        finish();
    }
});

运行结果

当点击BActivity的button2按钮时,执行了MainActivity的onActivityResult方法

com.example.dmdm.demo E/geziqiangcwrtwe: onActivityResult MainActivity -1

其中RESULT_OK的值就是-1

(PS:如果不设置FLAG_ACTIVITY_FORWARD_RESULT,就和《案例看源码--finish()源码分析2》一样了)

启动流程源码

  1. 启动总体流程是:
1. Activity#startActivity
2. Activity#startActivityForResult
3.Instrumentation#execStartActivity
4.ActivityManagerService#startActivityAsUser
5.ActivityStarter#startActivityMayWait
6.ActivityStarter#startActivityLocked
7.ActivityStarter#startActivity(本文重点分析此方法)
8.ActivityStarter#startActivityUnchecked
9.ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
10.ActivityStackSupervisor#resumeTopActivityUncheckedLocked
11.ActivityStackSupervisor#resumeTopActivityInnerLocked
12.ActivityStackSupervisor#startSpecificActivityLocked
13.ActivityStackSupervisor#realStartActivityLocked(注意之前暂停的activity如果状态是PAUSING时会直接返回)
14.ActivityStackSupervisor#activityPausedLocked
15.ActivityStackSupervisor#completePauseLocked
16.ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
17.ActivityStackSupervisor#resumeTopActivityUncheckedLocked
18.ActivityStackSupervisor#resumeTopActivityInnerLocked
19.ActivityStackSupervisor#startSpecificActivityLocked
20.ActivityStackSupervisor#realStartActivityLocked
21.app.thread.scheduleLaunchActivity(...)
  1. 重点看下ActivityStarter#startActivity方法
 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) {
            
            // 省略代码。。。
            
            ActivityRecord sourceRecord = null;
            ActivityRecord resultRecord = null;
            // 如果是Activity启动的话,resultTo就是执行startActivity方法的Activity。此时是AActivity
            if (resultTo != null) {
                // 此时就是获取AActivity在AMS中对应ActivityRecord
                sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
                if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                        "Will send result to " + resultTo + " " + sourceRecord);
                if (sourceRecord != null) {
                    // AActivity启动BActivity没有请求码,不进入if
                    if (requestCode >= 0 && !sourceRecord.finishing) {
                        resultRecord = sourceRecord;
                    }
                }
            }
            // 重点是这里,条件成立进入if
             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.
            // 表明AActivity不能通过startActivityForResult方法启动BActivity,否则异常
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }
            // sourceRecord此时AActivity对应,这里resultRecord就是MainActivity对应的ActivityRecord
            resultRecord = sourceRecord.resultTo;
            if (resultRecord != null && !resultRecord.isInStackLocked()) {
                resultRecord = null;
            }
            resultWho = sourceRecord.resultWho;
            // 复制一份MainActivity启动AActivity的请求码
            requestCode = sourceRecord.requestCode;
            sourceRecord.resultTo = null;
            if (resultRecord != null) {
                // 这个是取消MainActivity对BActivity请求的绑定
                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }
            // 省略部分代码
            
            // 这个是构造BActiivty对应的ActivityRecord,可以看到构造器内包含了resultRecord和requestCode。构造器内r.resultTo = resultRecord;r.requestCode = requestCode
             ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord);
                
            // 省略部分代码
            
            // 继续启动
            return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
        options, inTask, outActivity);
    }
  1. ActivityRecord#removeResultsLocked做了啥?
void removeResultsLocked(ActivityRecord from, String resultWho,
        int requestCode) {
    if (results != null) {
        for (int i=results.size()-1; i>=0; i--) {
            ActivityResult r = (ActivityResult)results.get(i);
            if (r.mFrom != from) continue;
            if (r.mResultWho == null) {
                if (resultWho != null) continue;
            } else {
                if (!r.mResultWho.equals(resultWho)) continue;
            }
            if (r.mRequestCode != requestCode) continue;

            results.remove(i);
        }
    }
}

就是判断results列表中有没有from,resultWho,requestCode都一样的记录,如果有的就移除

finish流程源码

  1. 启动总体流程是:
1.Activity#finish()
2.ActivityManagerService#finishActivity()
3.ActivityStack#requestFinishActivityLocked()
4.ActivityStack#finishActivityLocked()
  (1)如果当前是栈顶的Activity
    5.1 ActivityStack#startPausingLocked(),内部执行prev.app.thread.schedulePauseActivity()
    6.1 ActivityStack#schedulePauseTimeout
    7.1 ActivityStack#activityPausedLocked
    8.1 ActivityStack#completePauseLocked(内部将当前Activity添加到mStackSupervisor.mStoppingActivities中)
    9.1 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
    10.1 ActivityStackSupervisor#resumeTopActivityUncheckedLocked
    11.1 ActivityStackSupervisor#resumeTopActivityInnerLocked(内部有next.app.thread.scheduleSendResult和next.app.thread.scheduleResumeActivity)
    12.1 ActivityThread#scheduleResumeActivity
    13.1 ActivityThread#handleResumeActivity(内部有Looper.myQueue().addIdleHandler(new Idler()))
    14.1 ActivityManagerService#activityIdle
    15.1 ActivityStackSupervisor#activityIdleInternalLocked
    16.1 ActivityStack#finishCurrentActivityLocked
    17.1 ActivityStack#destroyActivityLocked(内部有 r.app.thread.scheduleDestroyActivity)
    18.1 ActivityThread#handleDestroyActivity
    19.1 ActivityThread#performDestroyActivity(内部有r.activity.performStop(r.mPreserveWindow)和mInstrumentation.callActivityOnDestroy(r.activity);)
    
 (2)如果当前Activity不处理Pauseing状态(开启新Activity之前会将回退栈中的Activity设置为Pauseing状态)
    5.2 ActivityStack#finishCurrentActivityLocked
    6.2 ActivityStack#destroyActivityLocked(内部有 r.app.thread.scheduleDestroyActivity)
    7.2 ActivityThread#handleDestroyActivity
    8.2 ActivityThread#performDestroyActivity(内部有r.activity.performStop(r.mPreserveWindow)和mInstrumentation.callActivityOnDestroy(r.activity);)
    
 (3)其他情况(本文案例就进入这个步骤)
    5.3  直接return掉,等completePauseLocked执行才处理
    6.3  Handler等待
    7.3  ActivityStackSupervisor#completePauseLocked
    8.3  ActivityStackSupervisor#finishCurrentActivityLocked
    9.3  ActivityStackSupervisor#addToStopping
    10.3 ActivityThread#scheduleResumeActivity
    11.3 ActivityThread#handleResumeActivity(内部有Looper.myQueue().addIdleHandler(new Idler()))
    12.3 ActivityManagerService#activityIdle
    13.3 ActivityStackSupervisor#activityIdleInternalLocked
    14.3 ActivityStack#finishCurrentActivityLocked
    15.3 ActivityStack#destroyActivityLocked(内部有 r.app.thread.scheduleDestroyActivity)
    16.3 ActivityThread#handleDestroyActivity
    17.3 ActivityThread#performDestroyActivity(内部有r.activity.performStop(r.mPreserveWindow)和mInstrumentation.callActivityOnDestroy(r.activity);)
  1. AActivity的finish方法,这个在《案例看源码--finish()源码分析2》已经分析过

  2. BAcitvity的finish方法,《案例看源码--finish()源码分析》也已经分析过,注意点是BAcitvity的resultTo此时是MainActivity

总结

  1. Acitivty启动流程主要使用的类是ActivityStarter和ActivityStack

  2. Acitivty结束流程主要使用的类是ActivityStack

  3. 启动和结束流程都有调用ActivityStackSupervisor#resumeFocusedStackTopActivityLocked来使栈顶activity可见。这个方法很重要,也很复杂!