基于android-8.1.0_r60

startActivity-android-8.0.jpg

注:这张图第14步到第15步不对。实际上是Activity1 onPaused之后,Activity才会执行第14步到第15步。

客户端调用

# 发起调用

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

startActivity调用的也是startActivityForResult, 只不是其中的requestCode为-1,而已。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        // 通知Instrumentation启动执行启动Activity的行为
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        // 传递Result,可以看到ActivityResult的ResultCode以及ResultData和requestCode的身影了。
        // 具体的传递过程发生在ActivityThread中。
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        ...
    }
    ...
}

# 接收调用

// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    // Instrumentation对于Activity也是由monitor的,monitor可以截获Activity的启动过程。
    // 插件化也可以在这里插入一个monitor,截获Activity的启动。
    // 调用Instrumentation的addMonitor即可注册monitor。
    // 默认情况下mActivityMonitors为空。
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                ActivityResult result = null;
                if (am.ignoreMatchingSpecificIntents()) {
                    // 回调onStartActivity,实现对于startActivity的拦截。
                    result = am.onStartActivity(intent);
                }
                if (result != null) {
                    am.mHits++;
                    return result;
                } else if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        // 获取AMS调用其来启动Activity,即调用startActivity。
        // 注意:下面的token就是后面ActivityManager中的resultTo
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

ActivityManagerService

# 远程响应

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
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());
}

@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) {
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}

# 启动准备

- startActivityMayWait

// frameworks/base/services/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,
            TaskRecord inTask, String reason) {
        // 如果intent中由FD,那么拒绝启动Activity以防导致FD的内存泄漏。
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        ...

        // 解析Intent,通过将intent中的数据转化为对应的解析数据
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

        // 解析ActivityInfo,比如Manifest中设置的对应的 <activity/> 标签
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        // 解析options
        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
        synchronized (mService) {
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }

            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            final long origId = Binder.clearCallingIdentity();
            ...
            // outRecord用于获得将要启动的Activity对应的ActivityRecord对象。ActivityRecord为Acitivity对应的Remote坑位,记录了这个Activity的token(即Activity中的token)、TaskRecord、ProcessRecord以及应用的ApplicationThread等所有信息。
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
            Binder.restoreCallingIdentity(origId);
            ...
            if (outResult != null) {
                outResult.result = res;
                if (res == ActivityManager.START_SUCCESS) {
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    if (outResult.result == START_TASK_TO_FRONT) {
                        res = START_TASK_TO_FRONT;
                    }
                }
                if (res == START_TASK_TO_FRONT) {
                    final ActivityRecord r = outRecord[0];

                    // ActivityRecord may represent a different activity, but it should not be in
                    // the resumed state.
                    if (r.nowVisible && r.state == RESUMED) {
                        outResult.timeout = false;
                        outResult.who = r.realActivity;
                        outResult.totalTime = 0;
                        outResult.thisTime = 0;
                    } else {
                        outResult.thisTime = SystemClock.uptimeMillis();
                        mSupervisor.waitActivityVisible(r.realActivity, outResult);
                        // Note: the timeout variable is not currently not ever set.
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (!outResult.timeout && outResult.who == null);
                    }
                }
            }

            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }
  • 从Intent解析出ResolveInfo
  • 从ResolveInfo解析ActivityInfo
  • 将options解析成ActivityOptions
  • 创建ActivityRecord数组用于接收对应的ActivityRecord

- startActivityLocked

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
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, TaskRecord inTask, String reason) {
    ...
    mLastStartActivityTimeMs = System.currentTimeMillis();
    // mLastStartActivityRecord同outActivity一样,用于获取返回结果。并将结果的第0个ActivityRecord设置到outActivity[0]中间去。
    mLastStartActivityRecord[0] = null;
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask);
    if (outActivity != null) {
        outActivity[0] = mLastStartActivityRecord[0];
    }
    // Aborted results are treated as successes externally, but we must track them internally.
    return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}

这一步无任何实际意义。

- startActivity

// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
/** 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, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;
    final Bundle verificationBundle = options != null ? options.popAppVerificationBundle() : null;
    ProcessRecord callerApp = null;
    if (caller != null) {
        // 通过发起方的applicaionThread对象查询其对应的进程信息。
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            // 如果调用者的进程不存在,那么抛出权限错误。
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    ...
    // sourceRecord即为调用者(resultTo)对应的ActivityRecord,即当前的发起方。
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            // 如果requestCode大于等于0,并且Activity不是关闭状态。
            // 则将sourceRecord赋值给resultRecord,即接受result的Activity对应的ActivityRecord。
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }

    final int launchFlags = intent.getFlags();

    // 如果包含了`FLAG_ACTIVITY_FORWARD_RESULT`这个flag,则将sourceRecord的resultTo设定为resultRecord。
    // 这段可以这么理解。加入A启动类B,B又启动了C,并且B到C是添加了`FLAG_ACTIVITY_FORWARD_RESULT`。
    // 这一段代码就是B到C的过程。其中sourceRecord也就是B对应的`resultTo`也就是A,如果A想获得C的结果。
    // 那么就将B的`resultTo`传递给C当作`resultTo`,即当前的`resultRecord`对象。
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 中转的Activity不能通过forResult的方式启动Activity,这里会抛出`START_FORWARD_AND_REQUEST_CONFLICT`
        if (requestCode >= 0) {
            ActivityOptions.abort(options);
            return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
        }
        resultRecord = sourceRecord.resultTo;
        if (resultRecord != null && !resultRecord.isInStackLocked()) {
            resultRecord = null;
        }
        resultWho = sourceRecord.resultWho;
        requestCode = sourceRecord.requestCode;
        sourceRecord.resultTo = null;
        if (resultRecord != null) {
            resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
        }
        if (sourceRecord.launchedFromUid == callingUid) {
            callingPackage = sourceRecord.launchedFromPackage;
        }
    }

    // component不可以为空
    if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
        err = ActivityManager.START_INTENT_NOT_RESOLVED;
    }

    // 如果ResolveInfo为空,则表示目标Activity不存在。为啥不在`resolveActivity`时抛出异常呢?
    if (err == ActivityManager.START_SUCCESS && aInfo == null) {
        err = ActivityManager.START_CLASS_NOT_FOUND;
    }

    ...

    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
    // 如果无法打开目标Activity,并且是forResult,那么将会收到一个`RESULT_CANCELED`事件。后面还会做其他检查,如果无法打开Activity,都会抛出RESULT_CANCED。
    if (err != START_SUCCESS) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(
                    -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }
    ...

    // 中间省略了需要用户从UI界面确认某些操作的行为。大致就是获取新的ResolveInfo,并持有先前。当用户确认后,再启动真正的目标界面。省略,这里来看一般情况如何处理。

    // 创建将要启动的Activity对应的ActivityRecord对象。此时,前面的各种数据都被新的ActivityRecord持有了。比如aInfoActivity信息(ActivityInfo)、resultRecord和requestCode用于处理forResult、sourceRecord调用方对应的ActivityRecord、callerApp即调用方的client(ActivityThread中的ApplicationThread信息)、以及options(点击位置等等信息都可以写在这里)
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, options, sourceRecord);
    if (outActivity != null) {
        outActivity[0] = r;
    }

    ...
    // 启动其它待启动列表中的Activity,这里面也是遍历`mPendingActivityLaunches`列表,调用下面的startActivity函数。
    doPendingActivityLaunchesLocked(false);
    // 上面做好了一系列的准备:解析ResolveInfo、调用方进程、resultRecord、权限、创建目标ActivityRecord等等条件,下面才是真正的启动过程。
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
            options, inTask, outActivity);
}

这一步生成一个“ActivityRecord”的过程, 包括确定caller信息/sourceRecord/resultRecord等等。

其中resultRecord用于记录原始的发起startActivityForResult的sourceRecord, 如果存在FORWARD这个flag, 则往前追溯(即sourceRecord.resultTo)resultRecord当作新的ActivityRecord的resultTo。

# 开始启动

  • startActivityUnchecked
// frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
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 we are not able to proceed, disassociate the activity from the task. Leaving an
        // activity in an incomplete state can lead to issues, such as performing operations
        // without a window container.
        if (!ActivityManager.isStartResultSuccessful(result)
                && mStartActivity.getTask() != null) {
            mStartActivity.getTask().removeActivity(mStartActivity);
        }
        mService.mWindowManager.continueSurfaceLayout();
    }

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

    return result;
}

// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);
    computeLaunchingTaskFlags();
    computeSourceStack();
    mIntent.setFlags(mLaunchFlags);
    ActivityRecord reusedActivity = getReusableIntentActivity();
    if (reusedActivity != null) {
        // 重用Activity的情况,这种情况都是当前Activity正在运行的例子,省略不做讨论。
    }
    ...
    final ActivityStack topStack = mSupervisor.mFocusedStack;
    final ActivityRecord topFocused = topStack.topActivity();
    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || mLaunchSingleTop || mLaunchSingleTask);
    if (dontStart) {
        // For paranoia, make sure we have correctly resumed the top activity.
        topStack.mLastPausedActivity = null;
        if (mDoResume) {
            mSupervisor.resumeFocusedStackTopActivityLocked();
        }
        ActivityOptions.abort(mOptions);
        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
            // 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;
        }
        deliverNewIntent(top);
        // Don't use mStartActivity.task to show the toast. We're not starting a new activity
        // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
        mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
                preferredLaunchDisplayId, topStack.mStackId);
        return START_DELIVERED_TO_TOP;
    }

    // 下面开始分配Activity对应的ActivityStack了。这里会优先考虑FLAG_ACTIVITY_NEW_TASK的情况,根据taskToAffiliate等判断栈。
    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;
    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        // FLAG_ACTIVITY_NEW_TASK
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(
                taskToAffiliate, preferredLaunchStackId, topStack);
    } else if (mSourceRecord != null) {
        // 直接使用调用方的栈
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        // 使用参数中的inTask对应的栈。正常情况下inTask一直为null
        result = setTaskFromInTask();
    } else {
        // 创建新栈
        setTaskToCurrentTopOrCreateNewTask();
    }
    if (result != START_SUCCESS) {
        return result;
    }
    // 根据LaunchMode以及flag等确认一个ActivityStack,
    // 并在对应的ActivityStack中完成Activity栈的位置等等。
    ...
    // 这里实际并未启动Activity,Activity的实例化也非这里触发。
    // 这里只是将mTartStack加入mTaskHistory的栈顶,当后面需要进程
    // 再启动Activity的时候需要从栈顶再都出来。
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    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");
            }
            // 通知Activity启动界面。
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);
        }
    } else {
        // 如果不启动界面,那么直接将其加入到最近任务中去。
        mTargetStack.addRecentActivityLocked(mStartActivity);
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
            preferredLaunchDisplayId, mTargetStack.mStackId);

    return START_SUCCESS;
}

private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
        boolean doResume, int startFlags, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
    reset();
    mStartActivity = r;
    ...
    sendNewTaskResultRequestIfNeeded();
    ...
    // 如果option可以通过`canTaskOverlayResume`控制启动的Activity是否进行resume行为,那么也可以将`mDoResume`设置为false,并且目标activity不会跑到前台。不resume,则意味着Activity只会onCreate,而不会onResume,则不会有任何界面。
    // TODO 待验证。
    if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
        r.mTaskOverlay = true;
        if (!mOptions.canTaskOverlayResume()) {
            final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
            final ActivityRecord top = task != null ? task.getTopActivity() : null;
            if (top != null && top.state != RESUMED) {

                // The caller specifies that we'd like to be avoided to be moved to the front,
                // so be it!
                mDoResume = false;
                mAvoidMoveToFront = true;
            }
        }
    }
    ...
    // FLAG_ACTIVITY_NO_ANIMATION用于标识是否不启动Activity动画
    mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
}

private void sendNewTaskResultRequestIfNeeded() {
    // 如果是forResult方式启动新的Activity的时候,添加了flag FLAG_ACTIVITY_NEW_TASK 那么会在启动Activity前直接返回一个CANCELED的消息。
    final ActivityStack sourceStack = mStartActivity.resultTo != null ? mStartActivity.resultTo.getStack() : null;
    if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
                mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
                null /* data */);
        // 清除resultTo
        mStartActivity.resultTo = null;
    }
}

private ActivityRecord getReusableIntentActivity() {
    boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || mLaunchSingleInstance || mLaunchSingleTask;
    putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
    ActivityRecord intentActivity = null;
    if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
        final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
        intentActivity = task != null ? task.getTopActivity() : null;
    } else if (putIntoExistingTask) {
        if (mLaunchSingleInstance) {
           intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                   mStartActivity.isHomeActivity());
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
            intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, !mLaunchSingleTask);
        } else {
            // Otherwise find the best task to put the activity in.
            intentActivity = mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId);
        }
    }
    return intentActivity;
}

这一步主要用于找到对应的ActivityStack, 即Activity被分配到的栈, 最终将其传递到ActivityStackSupervisor中执行具体的启动过程。

  • options.canTaskOverlayResume

控制启动的Activity是否进行resume行为,那么也可以将mDoResume设置为false,并且目标activity不会跑到前台。不resume,则意味着Activity只会onCreate,而不会onResume,则不会有任何界面。

需要在启动的options(Bundle),添加key为KEY_TASK_OVERLAY_CAN_RESUME的boolean类型值。同时制定一个taskId。

// ActivityOptions.java
private static final String KEY_TASK_OVERLAY_CAN_RESUME = "android.activity.taskOverlayCanResume";
private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";

这种情况要求指定taskId,因此目标Activity的launchMode不可以是SingleTask/SingleInstance等情况。

并且你还需要START_TASKS_FROM_RECENTS这个权限。这种方式很容易被Dennial。

  • FLAG_ACTIVITY_NO_ANIMATION

标识是否不启动Activity动画

# 小结

- ActivityManagerService

是一个大领导。主要工作是调度,使用不同接口提供不同服务。

接口内部实现,则是调度各个组件完成具体工作。并把结果返回。

最终,结果输出给调用方。作为一个调度方,它的工作就是枢纽,联络内外。

- ActivityStarter

负责启动Activity的前期准备。这些前期准备包括如下:

  • 解析Intent,生成ResolveInfo。

  • 通过Intent及其ResolveInfo,获取启动目标的ActivityInfo。

  • 解析ActivityOptions。

ActivityOptions是从启动时的最后一个参数options(Bundle实例)通过函数ActivityOptions.fromBundle(bOptions)解析而来。

这里面包含了很多影响着后面Activity启动的有用信息。比如,mLaunchBounds(即点击启动的位置)、动画、taskId、stackId、displayId等等。

  • 背景调查。

比如发起方的进程是否存在。检查权限,包括是否有权打开某页面,是否有权限进行某些设定。是否需要用户在界面授权才能进行某项行为。

  • 处理Result的输送。

比如,requestCode是否合法、是否FORWARD、是否NEW_TASK等等。

同时如果需要forResult的前提下,如果不能打开目标页面则立马发送一个CANCEL的结果等。

  • 生成目标的ActivityRecord。

这里会记录一系列数据,比如aInfoActivity信息(ActivityInfo)、resultRecord和requestCode用于处理forResult、sourceRecord调用方对应的ActivityRecord、callerApp即调用方的client(ActivityThread中的ApplicationThread信息)、以及ActivityOptions,调用方的进程id、uid等等。

  • 重用Activity。

比如一个目标Activity,已被打开。那么如果可以复用,则直接返回先前启动对应的ActivityRecord等信息。

  • 分配ActivityStack并启动Activity。

综合启动的flags以及launchMode以及sourceRecord等得出一个新页面对应的ActivityStack。Activity的栈管理也是在这里面管理的。

  • 判定是否需要resume

即是否调用目标Activity的onResume这一周期。也是在这里完成的。默认情况下,当你打开一个Activity的时候,其onResume都是会调用的。

特殊情况下,比如你有权在options中设定不OverlayResume等,也是可以不onResume的。

- ActivityStackSupervisor

用于管理ActivityStack以及控制Activity声明周期的调度等等。

真正唤起目标进程及发送消息到达ActivityThread,实例化Activity都是在ActivityStack中完成的。不过,启动进程最终还是要回到AMS调度到ZygoteProcess孵化子进程。

- 其他细节

  • requestCode大于等于0

否则将不会往resultRecord填充sourceRecord。

  • FLAG_ACTIVITY_FORWARD_RESULT,可以传递结果给最初的发起方。

即将当前的ActivityRecord中的resultTo设定为resultresultRecordresultRecord最后被最后一个被打开的Activity对应的ActivityRecord的resultTo持有。

  • FLAG_ACTIVITY_FORWARD_RESULT时,requestCode不可以有效。

否则认为捣乱,抛出冲突异常START_FORWARD_AND_REQUEST_CONFLICT。对应的消息为FORWARD_RESULT_FLAG used while also requesting a result。具体处理见InstrumentationcheckStartActivityResult函数。

  • ActivityRecord中会使用变量resultTo持有需要result的Activity对应的ActivityRecord。

  • FLAG_ACTIVITY_NEW_TASK这个标识,会让发起方直接收到一个CANCEL消息,并且再也没有然后了。

生命周期交替

# resumeFocusedStackTopActivityLocked

上面在ActivityStarter的startActivityUnchecked函数的最后,调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数。如下:

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (!readyToResume()) {
        return false;
    }
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    ...
    return false;
}

最后交给 resumeTopActivityUncheckedLocked 处理,如下:

// frameworks/base/services/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;
    }
    ...
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) { // Not ready yet!
        return false;
    }
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    ...
    final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0 && !lastResumedCanPip;
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);

    // mResumedActivity为当前已经Resumed的窗口
    if (mResumedActivity != null) {
        // 暂停调用方,最终调用的Activity会收到`schedulePauseActivity`消息。
        // 在这个情况下mResumedActivity就是调用方,而next则是目标Activity,即要启动的Activity。
        // 在startPausingLocked会将`mPausedActivity`设置为`mResumedActivity`,而`mResumedActivity`设定为null。
        // 因为目标Activity(即next)并未被执行,因此不能在这简单粗暴将next设置为`mResumedActivity`
        // startPausingLocked最后一个参数,叫做pauseImmediately,这里调用时传入的是false。这个参数在ApplicationThread中叫做dontReport
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }

    if (pausing && !resumeWhilePausing) {
        if (next.app != null && next.app.thread != null) {
            mService.updateLruProcessLocked(next.app, true, null);
        }
        // 直接返回,等待调用方的paused事件。
        // 等待onPause结束的回调, 运行`AMS.activityPaused()`函数中。
        // 回调之后还会进入`resumeTopActivityInnerLocked`这个函数。
        // 此时mResumedActivity则为空, 会执行到最后的`startSpecificActivityLocked`方法。
        return true;
    } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
            mStackSupervisor.allResumedActivitiesComplete()) {
        // 目标Activity已经是RESUMED状态且满足额外条件,则不继续执行启动Activity的行为。
        executeAppTransition(options);
        return true;
    }
    ...
    boolean anim = true;
    // 处理转场动画,非关注项,省略。
    ...
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        ...
    } else {
        // 启动目标Activity
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

可见:

  • 存在mResumedActivity时

mResumedActivity为当前已经Resumed的ActivityRecord。

暂停调用方,最终调用方Activity会收到schedulePauseActivity消息

在这个情况下mResumedActivity就是调用方,而next则是目标Activity,即要启动的Activity。

在startPausingLocked会将mPausedActivity设置为mResumedActivity,而mResumedActivity设定为null。同时startPausingLocked最后一个参数,叫做pauseImmediately,这里调用时传入的是false。这个参数在ApplicationThread中叫做dontReport

因为目标Activity(即next)并未被执行,因此不能在这简单粗暴将next设置为mResumedActivity

这种情况下,会跳转出去。此时并不会调用startSpecificActivityLocked执行scheduleLaunchActivity事件。

那么Activity到底什么时候执行呢?

Activity1 - onPause

- 发送pasued事件

resumeFocusedStackTopActivityLocked最后调用startPausingLocked函数通常调用方改onPause了,如下:

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    if (mPausingActivity != null) {
        if (!shouldSleepActivities()) {
            completePauseLocked(false, resuming);
        }
    }
    ActivityRecord prev = mResumedActivity;
    if (prev == null) {
        if (resuming == null) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }
    // 清空当前resumed的ActivityRecord
    mResumedActivity = null;
    // 正在pausing的Activity:将mResumedActivity设定为mPausingActivity
    mPausingActivity = prev;
    // 记录上次执行Paused的Record,也是mResumedActivity
    mLastPausedActivity = prev;
    mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
            || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
    prev.state = ActivityState.PAUSING;
    ...
    if (prev.app != null && prev.app.thread != null) {
        try {
            mService.updateUsageStats(prev, false);
            // 通知调用方的ApplicationThread你有一个`schedulePauseActivity`事件
            // app为ActivityRecord中的ProcessRecord,它持有了client端的ApplicationThread对象。
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                userLeaving, prev.configChangeFlags, pauseImmediately);
        }
    }
    ...
    return false;
}
  • 正在pausing的Activity:将mResumedActivity设定为mPausingActivity
  • 记录上次执行Paused的Record,也是mResumedActivity
  • 清空当前resumed的ActivityRecord即mResumedActivity
  • 通知调用方的ApplicationThread你有一个schedulePauseActivity事件。app为ActivityRecord中的ProcessRecord,它持有了client端的ApplicationThread对象,其中prev.appToken为remote端对应的ApplicationToken,即ActivityRecord$Token

此时ActivityThread的内部类ApplicationThreadschedulePauseActivity会触发。而在handlePauseActivity的最后,回调到ActivityManagerService。如下:

// ActivityThread.java
private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport, int seq) {
    ActivityClientRecord r = mActivities.get(token);
    if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
    if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
        return;
    }
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
        if (r.isPreHoneycomb()) {
            // 等待SharedPreference中apply的消息全部完成。
            QueuedWork.waitToFinish();
        }
        if (!dontReport) {
            try {
                // 回调:在上面可知dontReport为false,此时会回调到AMS。
                ActivityManager.getService().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }
}

可知dontReport为false,此时会通过ActivityManager.getService().activityPaused(token)回调到AMS。而其中的token,则是mPausingActivity的appToken。

- 接收onPaused完成的回调

activityPaused回调如下:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        // 通过appToken,找到remote对应的ActivitStack。
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

通过appToken,找到remote对应的ActivitStack。执行其activityPausedLocked方法:

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final void activityPausedLocked(IBinder token, boolean timeout) {
    // 通过token拿到对应的ActivityRecord对象
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        // 从上面可知,此时的r就是mPausingActivity。
        if (mPausingActivity == r) {
            mService.mWindowManager.deferSurfaceLayout();
            try {
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        }
    }
}

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;
    ...
    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!topStack.shouldSleepOrShutDownActivities()) {
            // 最终还是会回到熟悉的`resumeFocusedStackTopActivityLocked`函数。
            mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
        }
        ...
    }
    ...
}

可以看到通过token对象拿到ActivityRecord,可以判定这次就是我们之前正在pausing的Activity,然后在completePauseLocked中又回到了上面熟悉的resumeFocusedStackTopActivityLocked函数。

而这次调用resumeFocusedStackTopActivityLocked函数时,由于前面在startPausingLocked时已经将mResumedActivity置null,此时会跳过startPausingLocked分支逻辑,而执行startSpecificActivityLocked

到这里会真正启动我们要打开的Activity页面,其onCreate/onStart/onResume按序调用。

# Activity2 - onCreate

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
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, true);
    r.getStack().setLaunchTime(r);
    // 如果Activity对应的进程存在,那么就直接启动Activity即可。
    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;
        }
    }
    // 如果进程不存在,那么先启动进程。
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

这里分两种情况:

  • 如果Activity对应的进程存在,那么就直接启动Activity即可。
  • 如果进程不存在,那么先启动进程。

下面看看进程存在的情况:

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    if (!allPausedActivitiesComplete()) {
        return false;
    }
    final TaskRecord task = r.getTask();
    final ActivityStack stack = task.getStack();
    beginDeferResume();
    try {
        r.startFreezingScreenLocked(app, 0);
        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();
        r.app = app;
        if (mKeyguardController.isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }
        if (checkConfig) {
            final int displayId = r.getDisplayId();
            final Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    getDisplayOverrideConfiguration(displayId),
                    r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId);
            mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */,
                    displayId);
        }
        if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, true /* isTop */)) {
            r.setVisibility(true);
        }
        final int applicationInfoUid = (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();
        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();

        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
        }

        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            if (r.isHomeActivity()) {
                mService.mHomeProcess = task.mActivities.get(0).app;
            }
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(), PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showUnsupportedZoomDialogIfNeededLocked(r);
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            ProfilerInfo profilerInfo = null;
            ...
            app.hasShownUi = true;
            app.pendingUiClean = true;
            app.forceProcessStateUpTo(mService.mTopProcessState);
            final MergedConfiguration mergedConfiguration = new MergedConfiguration(mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
            r.setLastReportedConfiguration(mergedConfiguration);
            // 实例化Activity并onCreate/onResume等。
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

            if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                if (app.processName.equals(app.info.packageName)) {
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }
        } catch (RemoteException e) {
            ...
            throw e;
        }
    } finally {
        endDeferResume();
    }
    r.launchFailed = false;
    if (stack.updateLRUListLocked(r));
    if (andResume && readyToResume()) {
        stack.minimalResumeActivityLocked(r);
    } else {
        r.state = PAUSED;
    }
    if (isFocusedStack(stack)) {
        mService.startSetupActivityLocked();
    }
    if (r.app != null) {
        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
    }

    return true;
}

这里通过ProcessRecord拿到内部的ApplicationThread,向其发送一个scheduleLaunchActivity事件。这时Activity便启动了。

具体启动过程见handleLaunchActivity即可,不在这里的讨论范围。

# Activity1 - onStop

此时有debug截图,在realStartActivityLocked中会一路调到ActivityStackSupervisor的scheduleIdleLocked()函数

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final void scheduleIdleLocked() {
    mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}

private final class ActivityStackSupervisorHandler extends Handler {
    void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
        synchronized (mService) {
            activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
                    processPausingActivities, null);
        }
    }
    ...
}

// Checked.
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        boolean processPausingActivities, Configuration config) {
    ArrayList<ActivityRecord> finishes = null;
    ArrayList<UserState> startingUsers = null;
    int NS = 0;
    int NF = 0;
    boolean booting = false;
    boolean activityRemoved = false;
    ...
    // Atomically retrieve all of the other things to do.
    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
            true /* remove */, processPausingActivities);
    NS = stops != null ? stops.size() : 0;
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
            } else {
                stack.stopActivityLocked(r);
            }
        }
    }
    ...
}

scheduleIdleLocked()向handler发送一个IDLE_NOW_MSG事件,在事件的处理时,最终调用到ActivityStack的stopActivityLocked

// frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final void stopActivityLocked(ActivityRecord r) {
    ...
    if (r.app != null && r.app.thread != null) {
        adjustFocusedActivityStackLocked(r, "stopActivity");
        r.resumeKeyDispatchingLocked();
        try {
            r.stopped = false;
            r.state = STOPPING;
            if (!r.visible) {
                r.setVisible(false);
            }
            // 回调到ApplicationThread
            r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
            if (shouldSleepOrShutDownActivities()) {
                r.setSleeping(true);
            }
            Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
            mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
        }
        ...
    }
}

这里回调到ApplicationThread的scheduleStopActivity。此时便有了onStop生命周期。

其他

Activity的启动日志:

onStart和onRestart是Activity封装的,AMS并不存在对应的事件。

By @hyongbai 共45883个字

本文链接 http://yourbay.me/all-about-tech/2019/08/22/android-8.0-startActivity/