Activity相关学习-启动(3)

上一回讲到复用task,Activity的部分

流程

复用部分逻辑

1259        if (reusedActivity != null) {
1260            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1261            // still needs to be a lock task mode violation since the task gets cleared out and
1262            // the device would otherwise leave the locked task.
1263            if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
1264                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1265                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
1266                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1267                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1268            }
1269
1270            // True if we are clearing top and resetting of a standard (default) launch mode
1271            // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1272            final boolean clearTopAndResetStandardLaunchMode =
1273                    (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1274                            == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1275                    && mLaunchMode == LAUNCH_MULTIPLE;
1276
1277            // If mStartActivity does not have a task associated with it, associate it with the
1278            // reused activity's task. Do not do so if we're clearing top and resetting for a
1279            // standard launchMode activity.
1280            if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
1281                mStartActivity.setTask(reusedActivity.getTask());
1282            }
1283
1284            if (reusedActivity.getTask().intent == null) {
1285                // This task was started because of movement of the activity based on affinity...
1286                // Now that we are actually launching it, we can assign the base intent.
1287                reusedActivity.getTask().setIntent(mStartActivity);
1288            }
1289
1290            // This code path leads to delivering a new intent, we want to make sure we schedule it
1291            // as the first operation, in case the activity will be resumed as a result of later
1292            // operations.
1293            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
1294                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
1295                    || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
1296                final TaskRecord task = reusedActivity.getTask();
1297
1298                // In this situation we want to remove all activities from the task up to the one
1299                // being started. In most cases this means we are resetting the task to its initial
1300                // state.
1301                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1302                        mLaunchFlags); //将要复用的Activity上面的ActivityRecord都清除
                        //如果没有找到要复用的Activity,说明是第一次创建,则返回null
                       //注意,前面是task复用,这里如果top也不为null,那么就是ActivityRecord也复用了
1303
1304                // The above code can remove {@code reusedActivity} from the task, leading to the
1305                // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1306                // task reference is needed in the call below to
1307                // {@link setTargetStackAndMoveToFrontIfNeeded}.
1308                if (reusedActivity.getTask() == null) {
1309                    reusedActivity.setTask(task);
1310                }
1311
1312                if (top != null) { //如果找到了复用的Activity
1313                    if (top.frontOfTask) { //且复用的Activity是root Activity
1314                        // Activity aliases may mean we use different intents for the top activity,
1315                        // so make sure the task now has the identity of the new intent.
1316                        top.getTask().setIntent(mStartActivity); //重新设置task的Intent属性
1317                    }
1318                    deliverNewIntent(top); //调用Activity的omNewIntent方法
1319                }
1320            }

1322            mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
1323
1324            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity); 
                   //将复用task及其ActivityStack移到前台(如果必要的话) ;比如,使sourceTask和StartActivity的task不同,但是StartActivity指定的task已经存在了,可以复用(sourceTask和StartActivity的task不同,这也就是NEW_TASK这个flag的意思,可以找到可复用task的top running Activity,若没找到返回null),将其移到前台来即可;
1325
1326            final ActivityRecord outResult =
1327                    outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1328
1329            // When there is a reused activity and the current result is a trampoline activity,
1330            // set the reused activity as the result.
1331            if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1332                outActivity[0] = reusedActivity;
1333            }
1334
1335            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1336                // We don't need to start a new activity, and the client said not to do anything
1337                // if that is the case, so this is it!  And for paranoia, make sure we have
1338                // correctly resumed the top activity.
1339                resumeTargetStackIfNeeded(); 
1340                return START_RETURN_INTENT_TO_CALLER;
1341            }
1342
1343            if (reusedActivity != null) {
1344                setTaskFromIntentActivity(reusedActivity);
1345
1346                if (!mAddingToTask && mReuseTask == null) {
                        //mAddingToTask为false,且在复用的逻辑中,那么说明task中有复用Activity
1347                    // We didn't do anything...  but it was needed (a.k.a., client don't use that
1348                    // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
1349                   //按理说前面已经将Activity之上的全部清空了,保险起见,再调用一次resume的逻辑
1350                    resumeTargetStackIfNeeded();//其实就是调用
                          //如同一个栈中A->B->A,A是singleTask模式,那么task,Activity均可复用,这里就是先将B pause,然后A resume,最后B finish;介绍大致流程resumeFocusedStackTopActivityLocked
1351                    if (outActivity != null && outActivity.length > 0) {
1352                        outActivity[0] = reusedActivity;
1353                    }
1354
1355                    return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; //mMovedToFront 代表是否将ActivityStack移到了前台,如果本来就在前台,则为false
1356                }
1357            }
1358        }

ActivityStarter#deliverNewIntent

2092    private void deliverNewIntent(ActivityRecord activity) {
2093        if (mIntentDelivered) {
2094            return;
2095        }
2096
2097        ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTask());
2098        activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2099                mStartActivity.launchedFromPackage);
2100        mIntentDelivered = true;
2101    }

ActivityRecord#deliverNewIntentLocked

1464    /**
1465     * Deliver a new Intent to an existing activity, so that its onNewIntent()
1466     * method will be called at the proper time.
1467     */
1468    final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
1469        // The activity now gets access to the data associated with this Intent.
1470        service.grantUriPermissionFromIntentLocked(callingUid, packageName,
1471                intent, getUriPermissionsLocked(), userId);
1472        final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
1473        boolean unsent = true;
1474        final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
1475
1476        // We want to immediately deliver the intent to the activity if:
1477        // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1478        //   the user to see the visual effects caused by the intent delivery now.
1479        // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
            //当Activity处于paused或者resumed状态(用户还可见时,调用Activity的onNewIntent)
1480        if ((mState == RESUMED || mState == PAUSED
1481                || isTopActivityWhileSleeping) && app != null && app.thread != null) {
1482            try {
1483                ArrayList ar = new ArrayList<>(1);
1484                ar.add(rintent);
1485                service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
1486                        NewIntentItem.obtain(ar, mState == PAUSED));
1487                unsent = false; //调用onNewIntent
1488            } catch (RemoteException e) {
1489                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
1490            } catch (NullPointerException e) {
1491                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
1492            }
1493        }
1494        if (unsent) {
                   //将intent加入到ActivityRecord中的newIntents队列
1495            addNewIntentLocked(rintent);
1496        }
1497    }

如何调用Activity相关的声明周期函数呢?大致逻辑如下

ClientLifecycleManager#scheduleTransaction
56    /**
57     * Schedule a single lifecycle request or callback to client activity.
58     * @param client Target client.
59     * @param activityToken Target activity token.
60     * @param stateRequest A request to move target activity to a desired lifecycle state.
61     * @throws RemoteException
62     *
63     * @see ClientTransactionItem
64     */
65    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
66            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
67        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
68                stateRequest);
69        scheduleTransaction(clientTransaction);
70    }

38    /**
39     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
40     * @param transaction A sequence of client transaction items.
41     * @throws RemoteException
42     *
43     * @see ClientTransaction
44     */
45    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
46        final IApplicationThread client = transaction.getClient();
47        transaction.schedule();
48        if (!(client instanceof Binder)) {
49            // If client is not an instance of Binder - it's a remote call and at this point it is
50            // safe to recycle the object. All objects used for local calls will be recycled after
51            // the transaction is executed on client in ActivityThread.
52            transaction.recycle();
53        }
54    }
55
ClientTransaction#schedule
118    /**
119     * Schedule the transaction after it was initialized. It will be send to client and all its
120     * individual parts will be applied in the following sequence:
121     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
122     *    that needs to be done before actually scheduling the transaction for callbacks and
123     *    lifecycle state request.
124     * 2. The transaction message is scheduled.
125     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
126     *    all callbacks and necessary lifecycle transitions.
127     */
128    public void schedule() throws RemoteException {
129        mClient.scheduleTransaction(this);
130    }

53    /** Target client. */
54    private IApplicationThread mClient;

我们同样注意到

public final class ActivityThread extends ClientTransactionHandler 

ClientTransactionHandler#scheduleTransaction
42    /** Prepare and schedule transaction for execution. */
43    void scheduleTransaction(ClientTransaction transaction) {
44        transaction.preExecute(this);
45        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
46    }
ActivityThread#handleMessage
1809                case EXECUTE_TRANSACTION:
1810                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
1811                    mTransactionExecutor.execute(transaction);
1812                    if (isSystem()) {
1813                        // Client transactions inside system process are recycled on the client side
1814                        // instead of ClientLifecycleManager to avoid being cleared before this
1815                        // message is handled.
1816                        transaction.recycle();
1817                    }
TransactionExecutor#execute
    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
TransactionExecutor#executeLifecycleState
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        log("Resolving lifecycle state: " + lifecycleItem);

        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }

        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

执行对应ActivityLifecycleItem的excute,如

NewIntentItem#execute
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
        client.handleNewIntent(token, mIntents, mPause);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
ActivityThread#handleNewIntent
3142    @Override
3143    public void handleNewIntent(IBinder token, List intents, boolean andPause) {
3144        performNewIntents(token, intents, andPause);
3145    }


3115    void performNewIntents(IBinder token, List intents, boolean andPause) {
3116        final ActivityClientRecord r = mActivities.get(token);
3117        if (r == null) {
3118            return;
3119        }
3120
3121        final boolean resumed = !r.paused;
3122        if (resumed) {
3123            r.activity.mTemporaryPause = true;
3124            mInstrumentation.callActivityOnPause(r.activity);
3125        }
3126        checkAndBlockForNetworkAccess();
3127        deliverNewIntents(r, intents);
3128        if (resumed) {
3129            r.activity.performResume(false, "performNewIntents");
3130            r.activity.mTemporaryPause = false;
3131        }
3132
3133        if (r.paused && andPause) {
3134            // In this case the activity was in the paused state when we delivered the intent,
3135            // to guarantee onResume gets called after onNewIntent we temporarily resume the
3136            // activity and pause again as the caller wanted.
3137            performResumeActivity(token, false, "performNewIntents");
3138            performPauseActivityIfNeeded(r, "performNewIntents");
3139        }
3140    }

以上全是在Activity的服务端执行的逻辑

回到task,Activity复用的逻辑

ActivityStarter#setTargetStackAndMoveToFrontIfNeeded

保证复用的task,stack在前台

1855    /**
1856     * Figure out which task and activity to bring to front when we have found an existing matching
1857     * activity record in history. May also clear the task if needed.
1858     * @param intentActivity Existing matching activity.
1859     * @return {@link ActivityRecord} brought to front.
1860     */
1861    private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
1862        mTargetStack = intentActivity.getStack(); //得到reusedActivity相应的stack
1863        mTargetStack.mLastPausedActivity = null;
1864        // If the target task is not in the front, then we need to bring it to the front...
1865        // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1866        // the same behavior as if a new instance was being started, which means not bringing it
1867        // to the front if the caller is not itself in the front.
1868        final ActivityStack focusStack = mSupervisor.getFocusedStack();
1869        ActivityRecord curTop = (focusStack == null)
1870                ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
1871
1872        final TaskRecord topTask = curTop != null ? curTop.getTask() : null;
1873        if (topTask != null
1874                && (topTask != intentActivity.getTask() || topTask != focusStack.topTask())
1875                && !mAvoidMoveToFront) { //针对task需要移动到前台的情况
                   //要复用的task不是当前focus stack的top task
1876            mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1877            if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
1878                    mSourceStack.getTopActivity().getTask() == mSourceRecord.getTask())) {
1879                // We really do want to push this one into the user's face, right now.
1880                if (mLaunchTaskBehind && mSourceRecord != null) {
1881                    intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
1882                }
1883
1884                // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1885                // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1886                // So no point resuming any of the activities here, it just wastes one extra
1887                // resuming, plus enter AND exit transitions.
1888                // Here we only want to bring the target stack forward. Transition will be applied
1889                // to the new activity that's started after the old ones are gone.
1890                final boolean willClearTask =
1891                        (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1892                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1893                if (!willClearTask) {
1894                    final ActivityStack launchStack = getLaunchStack(
1895                            mStartActivity, mLaunchFlags, mStartActivity.getTask(), mOptions);
                        //getLaunchStack返回The stack to use for the launch or INVALID_STACK_ID.
1896                    final TaskRecord intentTask = intentActivity.getTask();
1897                    if (launchStack == null || launchStack == mTargetStack) {
1898                        // We only want to move to the front, if we aren't going to launch on a
1899                        // different stack. If we launch on a different stack, we will put the
1900                        // task on top there.
                            //将要复用的task放到stack前面,并将改ActivityStack也设为focus
1901                        mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1902                                mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
1903                        mMovedToFront = true;
1904                    } else if (launchStack.inSplitScreenWindowingMode()) {
1905                        if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1906                            // If we want to launch adjacent and mTargetStack is not the computed
1907                            // launch stack - move task to top of computed stack.
1908                            intentTask.reparent(launchStack, ON_TOP,
1909                                    REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1910                                    "launchToSide");
1911                        } else {
1912                            // TODO: This should be reevaluated in MW v2.
1913                            // We choose to move task to front instead of launching it adjacent
1914                            // when specific stack was requested explicitly and it appeared to be
1915                            // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
1916                            mTargetStack.moveTaskToFrontLocked(intentTask,
1917                                    mNoAnimation, mOptions, mStartActivity.appTimeTracker,
1918                                    "bringToFrontInsteadOfAdjacentLaunch");
1919                        }
1920                        mMovedToFront = launchStack != launchStack.getDisplay()
1921                                .getTopStackInWindowingMode(launchStack.getWindowingMode());
1922                    } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
1923                        // Target and computed stacks are on different displays and we've
1924                        // found a matching task - move the existing instance to that display and
1925                        // move it to front.
1926                        intentActivity.getTask().reparent(launchStack, ON_TOP,
1927                                REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1928                                "reparentToDisplay");
1929                        mMovedToFront = true;
1930                    } else if (launchStack.isActivityTypeHome()
1931                            && !mTargetStack.isActivityTypeHome()) {
1932                        // It is possible for the home activity to be in another stack initially.
1933                        // For example, the activity may have been initially started with an intent
1934                        // which placed it in the fullscreen stack. To ensure the proper handling of
1935                        // the activity based on home stack assumptions, we must move it over.
1936                        intentActivity.getTask().reparent(launchStack, ON_TOP,
1937                                REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1938                                "reparentingHome");
1939                        mMovedToFront = true;
1940                    }
1941                    mOptions = null;
1942
1943                    // We are moving a task to the front, use starting window to hide initial drawn
1944                    // delay.
1945                    intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
1946                            true /* taskSwitch */);
1947                }
1948            }
1949        }
1950        // Need to update mTargetStack because if task was moved out of it, the original stack may
1951        // be destroyed.
1952        mTargetStack = intentActivity.getStack();
1953        if (!mMovedToFront && mDoResume) {
1954            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
1955                    + " from " + intentActivity);
1956            mTargetStack.moveToFront("intentActivityFound");
1957        }
1958
1959        mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(),
1960                WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
1961
1962        // If the caller has requested that the target task be reset, then do so.
1963        if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1964            return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
1965        }
1966        return intentActivity;
1967    }

ActivityStack#moveTaskToFrontLocked

4651    final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options,
4652            AppTimeTracker timeTracker, String reason) {
4653        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
4654
4655        final ActivityStack topStack = getDisplay().getTopStack();
4656        final ActivityRecord topActivity = topStack != null ? topStack.getTopActivity() : null;
4657        final int numTasks = mTaskHistory.size();
4658        final int index = mTaskHistory.indexOf(tr);
4659        if (numTasks == 0 || index < 0)  {
4660            // nothing to do!
4661            if (noAnimation) {
4662                ActivityOptions.abort(options);
4663            } else {
4664                updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
4665            }
4666            return;
4667        }
4668
4669        if (timeTracker != null) {
4670            // The caller wants a time tracker associated with this task.
4671            for (int i = tr.mActivities.size() - 1; i >= 0; i--) {
4672                tr.mActivities.get(i).appTimeTracker = timeTracker;
4673            }
4674        }
4675
4676        try {
4677            // Defer updating the IME target since the new IME target will try to get computed
4678            // before updating all closing and opening apps, which can cause the ime target to
4679            // get calculated incorrectly.
4680            getDisplay().deferUpdateImeTarget();
4681
4682            // Shift all activities with this task up to the top
4683            // of the stack, keeping them in the same internal order.
4684            insertTaskAtTop(tr, null); //将task放到当前ActivityStack的top位置
4685
4686            // Don't refocus if invisible to current user
4687            final ActivityRecord top = tr.getTopActivity();
4688            if (top == null || !top.okToShowLocked()) {
4689                if (top != null) {
4690                    mStackSupervisor.mRecentTasks.add(top.getTask());
4691                }
4692                ActivityOptions.abort(options);
4693                return;
4694            }
4695
4696            // Set focus to the top running activity of this stack.
                   //得到当前stack的top running Activity
4697            final ActivityRecord r = topRunningActivityLocked();
                  //然后调用到这里,将当前栈设置为focus
4698            mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason); 
4699
4700            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
4701            if (noAnimation) {
4702                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
4703                if (r != null) {
4704                    mStackSupervisor.mNoAnimActivities.add(r);
4705                }
4706                ActivityOptions.abort(options);
4707            } else {
4708                updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
4709            }
4710            // If a new task is moved to the front, then mark the existing top activity as
4711            // supporting
4712
4713            // picture-in-picture while paused only if the task would not be considered an oerlay
4714            // on top
4715            // of the current activity (eg. not fullscreen, or the assistant)
4716            if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
4717                    options)) {
4718                topActivity.supportsEnterPipOnTaskSwitch = true;
4719            }
4720
4721            mStackSupervisor.resumeFocusedStackTopActivityLocked();
                //然后调用到这里,在resumeTopActivityInnerLocked中的pauseBackStacks,将上一个stack中的Activity pause
               //resumeFocusedStackTopActivityLocked可以等到后面再说
4722            EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
4723
4724            mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
4725        } finally {
4726            getDisplay().continueUpdateImeTarget();
4727        }
4728    }
ActivityStackSupervisor#moveFocusableActivityStackToFrontLocked

将ActivityRecord所在stack移到前台,并设置为focus

3411    /** Move activity with its stack to front and make the stack focused. */
3412    boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
3413        if (r == null || !r.isFocusable()) {
3414            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
3415                    "moveActivityStackToFront: unfocusable r=" + r);
3416            return false;
3417        }
3418
3419        final TaskRecord task = r.getTask();
3420        final ActivityStack stack = r.getStack();
3421        if (stack == null) {
3422            Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: r="
3423                    + r + " task=" + task);
3424            return false;
3425        }
3426
3427        if (stack == mFocusedStack && stack.topRunningActivityLocked() == r) {
3428            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
3429                    "moveActivityStackToFront: already on top, r=" + r);
3430            return false;
3431        }
3432
3433        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
3434                "moveActivityStackToFront: r=" + r);
3435
3436        stack.moveToFront(reason, task);
3437        return true;
3438    }
ActivityStack#moveToFront
1022    /**
1023     * @param reason The reason for moving the stack to the front.
1024     * @param task If non-null, the task will be moved to the top of the stack.
1025     * */
1026    void moveToFront(String reason, TaskRecord task) {
1027        if (!isAttached()) {
1028            return;
1029        }
1030
1031        final ActivityDisplay display = getDisplay();
1032
1033        if (inSplitScreenSecondaryWindowingMode()) {
1034            // If the stack is in split-screen seconardy mode, we need to make sure we move the
1035            // primary split-screen stack forward in the case it is currently behind a fullscreen
1036            // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't
1037            // cutting between them.
1038            // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280.
1039            final ActivityStack topFullScreenStack =
1040                    display.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
1041            if (topFullScreenStack != null) {
1042                final ActivityStack primarySplitScreenStack = display.getSplitScreenPrimaryStack();
1043                if (display.getIndexOf(topFullScreenStack)
1044                        > display.getIndexOf(primarySplitScreenStack)) {
1045                    primarySplitScreenStack.moveToFront(reason + " splitScreenToTop");
1046                }
1047            }
1048        }
1049
1050        if (!isActivityTypeHome() && returnsToHomeStack()) {
1051            // Make sure the home stack is behind this stack since that is where we should return to
1052            // when this stack is no longer visible.
1053            mStackSupervisor.moveHomeStackToFront(reason + " returnToHome");
1054        }
1055
1056        display.positionChildAtTop(this);
1057        mStackSupervisor.setFocusStackUnchecked(reason, this);//将当前的ActivityStack设置为focus
1058        if (task != null) {
1059            insertTaskAtTop(task, null); //task放到stack的top位置
1060            return;
1061        }
1062    }
ActivityStackSupervisor#setFocusStackUnchecked
713    /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
714    void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
715        if (!focusCandidate.isFocusable()) {
716            // The focus candidate isn't focusable. Move focus to the top stack that is focusable.
717            focusCandidate = getNextFocusableStackLocked(focusCandidate, false /* ignoreCurrent */);
718        }
719
720        if (focusCandidate != mFocusedStack) {
721            mLastFocusedStack = mFocusedStack;
722            mFocusedStack = focusCandidate;
723
724            EventLogTags.writeAmFocusedStack(
725                    mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(),
726                    mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
727        }
728
729        final ActivityRecord r = topRunningActivityLocked();
730        if (mService.mBooting || !mService.mBooted) {
731            if (r != null && r.idle) {
732                checkFinishBootingLocked();
733            }
734        }
735    }

回到复用的逻辑

ActivityStarter#setTaskFromIntentActivity

setTaskFromIntentActivity也是针对task复用而言的;这个是用来设置复用task相关的一些属性的;注意mAddingToTask,个人理解,当mAddingToTask的值为true时,代表要创建新的Activity添加到复用task中

2130    private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2131        if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2132                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2133            // The caller has requested to completely replace any existing task with its new
2134            // activity. Well that should not be too hard...
2135            // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2136            // removed from calling performClearTaskLocked (For example, if it is being brought out
2137            // of history or if it is finished immediately), thus disassociating the task. Also note
2138            // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2139            // launching another activity.
2140            // TODO(b/36119896):  We shouldn't trigger activity launches in this path since we are
2141            // already launching one.
2142            final TaskRecord task = intentActivity.getTask();
2143            task.performClearTaskLocked();
2144            mReuseTask = task;
2145            mReuseTask.setIntent(mStartActivity);
2146        } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2147                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2148            ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
2149                    mLaunchFlags);
2150            if (top == null) {
                    //比如这里,虽然复用task,但是在task中找不到复用的ActivityRecord;如要启动的flag包含NEW_TASK;但是这个Activity是第一次启动
                   //则mAddingToTask为true,代表要创建new Activity放到复用task中
          
2151                // A special case: we need to start the activity because it is not currently
2152                // running, and the caller has asked to clear the current task to have this
2153                // activity at the top.
2154                mAddingToTask = true;
2155
2156                // We are no longer placing the activity in the task we previously thought we were.
2157                mStartActivity.setTask(null);
                    //注意这里将StartActivity的task置空,后续还会通过setTaskFromSourceRecord()赋值
2158                // Now pretend like this activity is being started by the top of its task, so it
2159                // is put in the right place.
2160                mSourceRecord = intentActivity;
                        //mSourceRecord的值赋值为intentActivity
2161                final TaskRecord task = mSourceRecord.getTask();
2162                if (task != null && task.getStack() == null) {
2163                    // Target stack got cleared when we all activities were removed above.
2164                    // Go ahead and reset it.
2165                    mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
2166                            mLaunchFlags, mOptions);
2167                    mTargetStack.addTask(task,
2168                            !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2169                }
2170            }
2171        } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
2172            // In this case the top activity on the task is the same as the one being launched,
2173            // so we take that as a request to bring the task to the foreground. If the top
2174            // activity in the task is the root activity, deliver this new intent to it if it
2175            // desires.
2176            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2177                        || LAUNCH_SINGLE_TOP == mLaunchMode)
2178                    && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
2179                if (intentActivity.frontOfTask) {
2180                    intentActivity.getTask().setIntent(mStartActivity);
2181                }
2182                deliverNewIntent(intentActivity);
2183            } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
2184                // In this case we are launching the root activity of the task, but with a
2185                // different intent. We should start a new instance on top.
2186                mAddingToTask = true;
2187                mSourceRecord = intentActivity;
2188            }
2189        } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2190            // In this case an activity is being launched in to an existing task, without
2191            // resetting that task. This is typically the situation of launching an activity
2192            // from a notification or shortcut. We want to place the new activity on top of the
2193            // current task.
2194            mAddingToTask = true;
2195            mSourceRecord = intentActivity;
2196        } else if (!intentActivity.getTask().rootWasReset) {
2197            // In this case we are launching into an existing task that has not yet been started
2198            // from its front door. The current task has been brought to the front. Ideally,
2199            // we'd probably like to place this new task at the bottom of its stack, but that's
2200            // a little hard to do with the current organization of the code so for now we'll
2201            // just drop it.
2202            intentActivity.getTask().setIntent(mStartActivity);
2203        }
2204    }

ActivityStarter#resumeTargetStackIfNeeded

上面说道resumeTargetStackIfNeeded,这也只是在复用task的时候才会调用的
A->B->A A为singleTask模式的大致流程

1477            if (reusedActivity != null) {
1478                setTaskFromIntentActivity(reusedActivity);
1479
1480                if (!mAddingToTask && mReuseTask == null) {
1481                    // We didn't do anything...  but it was needed (a.k.a., client don't use that
1482                    // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
1483                   //mAddingToTask = false,不用创建新的Activity,那么就是复用原来的
1484                    resumeTargetStackIfNeeded(); //调用resumeTargetStackIfNeeded
1485                    if (outActivity != null && outActivity.length > 0) {
1486                        outActivity[0] = reusedActivity;
1487                    }
1488
1489                    return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
1490                }
1491            }
2206    private void resumeTargetStackIfNeeded() {
2207        if (mDoResume) {
2208            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
2209        } else {
2210            ActivityOptions.abort(mOptions);
2211        }
2212        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
2213    }
ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
2307    boolean resumeFocusedStackTopActivityLocked(
2308            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
2309
2310        if (!readyToResume()) {
2311            return false;
2312        }
2313
2315        // if resume one non-fullscreen task, also resume the other one
2316        boolean resumed = false;
2317        if (targetStack != null && isFocusedStack(targetStack)) {
2321
2331            if (target != null && target.getState() == RESUMED && mNeedScheduleIdle) {
2332                scheduleIdleLocked();
2333                mNeedScheduleIdle = false;
2334                if (target.getTask().inMultiWindowMode()) {
2335                    return false;
2336                }
2337            }
2338            resumed = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
2339        } else {
2340            ActivityStack recentsStack = getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS);
2341            if (mLaunchRecentsFromGesture && recentsStack != null && !mHasResumeRecentsBehind
2342                    && !mStopLaunchRecentsBehind) {
2343                recentsStack.resumeTopActivityUncheckedLocked(null, null);
2344            } else {
2345                final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
2346                if (r == null || r.getState() != RESUMED) {
2347                    mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
2348                } else if (r.getState() == RESUMED) {
2349                    if (!r.getTask().inMultiWindowMode()) {
2350                        mFocusedStack.executeAppTransition(targetOptions);
2351                    }
2352                    if (mNeedScheduleIdle) {
2353                        scheduleIdleLocked();
2354                        mNeedScheduleIdle = false;
2355                    }
2356                    return false;
2357                }
2358            }
2359        }
2360        // resume non-fullscreen task
2361        if (mFocusedStack.topTask() != null && mFocusedStack.topTask().inMultiWindowMode()
2362                && !mService.isSleepingOrShuttingDownLocked()) {
2364            ActivityStack multiWindowStack = null;
2365            if (mFocusedStack.inSplitScreenPrimaryWindowingMode()) {
2366                multiWindowStack = mFocusedStack.getDisplay().getTopStackInWindowingMode(
2367                        WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
2368            } else if (mFocusedStack.inSplitScreenSecondaryWindowingMode()) {
2369                multiWindowStack = mFocusedStack.getDisplay().getTopStackInWindowingMode(
2370                        WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
2371            }
2372
2373            if (multiWindowStack != null
2374                    && multiWindowStack.shouldBeVisible(null)) {
2375                final ActivityRecord r = multiWindowStack.topRunningActivityLocked();
2376                if (r != null && r.getState() != RESUMED && r.getTask().inMultiWindowMode()) {
2377                    multiWindowStack.resumeTopActivityUncheckedLocked(null, null);
2378                }
2379            }
2380        }
2381        return resumed;
2382        // END
2383    }

ActivityStack#resumeTopActivityUncheckedLocked

2397    /**
2398     * Ensure that the top activity in the stack is resumed.
2399     *
2400     * @param prev The previously resumed activity, for when in the process
2401     * of pausing; can be null to call from elsewhere.
2402     * @param options Activity options.
2403     *
2404     * @return Returns true if something is being resumed, or false if
2405     * nothing happened.
2406     *
2407     * NOTE: It is not safe to call this method directly as it can cause an activity in a
2408     *       non-focused stack to be resumed.
2409     *       Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
2410     *       right activity for the current system state.
2411     */
2412    @GuardedBy("mService")
2413    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
2414        if (mStackSupervisor.inResumeTopActivity) {
2415            // Don't even start recursing.
2416            return false;
2417        }
2418
2419        boolean result = false;
2420        try {
2421            // Protect against recursion.
2422            mStackSupervisor.inResumeTopActivity = true;
2423            result = resumeTopActivityInnerLocked(prev, options);
2424
2425            // When resuming the top activity, it may be necessary to pause the top activity (for
2426            // example, returning to the lock screen. We suppress the normal pause logic in
2427            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
2428            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
2429            // to ensure any necessary pause logic occurs. In the case where the Activity will be
2430            // shown regardless of the lock screen, the call to
2431            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
2432            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
2433            if (next == null || !next.canTurnScreenOn()) {
2434                checkReadyForSleep();
2435            }
2436        } finally {
2437            mStackSupervisor.inResumeTopActivity = false;
2438        }
2439
2440        return result;
2441    }

调用resumeTopActivityInnerLocked,这个逻辑比较复杂,放在下面的文章中讲

你可能感兴趣的:(Activity相关学习-启动(3))