android之AMS学习攻克

Activity相关学习-启动(6)-resumeTopActi

2019-01-13  本文已影响0人  weiinter105

前言

本周重点介绍上章末尾resumeTopActivityInnerLocked接口中的一些逻辑

相关逻辑

ActivityStack#allPausedActivitiesComplete

只要有一个Activity不处于r.isState(PAUSED, STOPPED, STOPPING)状态,就等待

1100    boolean allPausedActivitiesComplete() {
1101        boolean pausing = true;
1102        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1103            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
1104            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1105                final ActivityStack stack = display.getChildAt(stackNdx);
1106                final ActivityRecord r = stack.mPausingActivity;
1107                if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
1108                    if (DEBUG_STATES) {
1109                        Slog.d(TAG_STATES,
1110                                "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
1111                        pausing = false;
1112                    } else {
1113                        return false;
1114                    }
1115                }
1116            }
1117        }
1118        return pausing;
1119    }

ActivityStack#pauseBackStacks

对后台stack中原来的resumed Activity执行startPausingLocked操作,针对startActivity的过程中切换了stack的情况

1075    /**
1076     * Pause all activities in either all of the stacks or just the back stacks.
1077     * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
1078     * @param resuming The resuming activity.
1079     * @param dontWait The resuming activity isn't going to wait for all activities to be paused
1080     *                 before resuming.
1081     * @return true if any activity was paused as a result of this call.
1082     */
1083    boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
1084        boolean someActivityPaused = false;
1085        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
1086            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
1087            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
1088                final ActivityStack stack = display.getChildAt(stackNdx);
1089                if (!isFocusedStack(stack) && stack.getResumedActivity() != null) {
1090                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
1091                            " mResumedActivity=" + stack.getResumedActivity());
1092                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
1093                            dontWait);
1094                }
1095            }
1096        }
1097        return someActivityPaused;
1098    }

注意,stack.getResumedActivity返回相应的 mResumedActivity 属性,在startPausingLocked中会置为null

ActivityStack#startPausingLocked

1408    /**
1409     * Start pausing the currently resumed activity.  It is an error to call this if there
1410     * is already an activity being paused or there is no resumed activity.
1411     *
1412     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
1413     * @param uiSleeping True if this is happening with the user interface going to sleep (the
1414     * screen turning off).
1415     * @param resuming The activity we are currently trying to resume or null if this is not being
1416     *                 called as part of resuming the top activity, so we shouldn't try to instigate
1417     *                 a resume here if not null.
1418     * @param pauseImmediately True if the caller does not want to wait for the activity callback to
1419     *                         complete pausing.
1420     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
1421     * it to tell us when it is done.
1422     */
1423    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
1424            ActivityRecord resuming, boolean pauseImmediately) {
1425        if (mPausingActivity != null) { 
1426            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
1427                    + " state=" + mPausingActivity.getState());
1428            if (!shouldSleepActivities()) {
1429                // Avoid recursion among check for sleep and complete pause during sleeping.
1430                // Because activity will be paused immediately after resume, just let pause
1431                // be completed by the order of activity paused from clients.
1432                completePauseLocked(false, resuming); //如果stack中有正在pausing的Activity,那么直接走completePauseLocked逻辑
1433            }
1434        }
1435        ActivityRecord prev = mResumedActivity; //将当前stack的resumed Activity保存下来
1436
1437        if (prev == null) {
1438            if (resuming == null) {
1439                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
1440                mStackSupervisor.resumeFocusedStackTopActivityLocked();
1441            }
1442            return false;
1443        }
1444
1445        if (prev == resuming) {
1446            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
1447            return false;
1448        }
1449
1450        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
1451        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
1452
1453        if (mActivityTrigger != null) {
1454            mActivityTrigger.activityPauseTrigger(prev.intent, prev.info, prev.appInfo);
1455        }
1456
1457        if (mActivityPluginDelegate != null && getWindowingMode() != WINDOWING_MODE_UNDEFINED) {
1458            mActivityPluginDelegate.activitySuspendNotification
1459                (prev.appInfo.packageName, getWindowingMode() == WINDOWING_MODE_FULLSCREEN, true);
1460        }
1461
1462        mResumedActivity = null; //mResumedActivity置空
1463        mPausingActivity = prev; //mPausingActivity为上一个resumed的Activity
1464        mLastPausedActivity = prev;
1465        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
1466                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
1467        prev.setState(PAUSING, "startPausingLocked");
1468        prev.getTask().touchActiveTime();
1469        clearLaunchTime(prev);
1470
1471        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
1472
1473        mService.updateCpuStats();
1474
1475        if (prev.app != null && prev.app.thread != null) {
1476            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
1477            try {
1478                EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
1479                        prev.shortComponentName, "userLeaving=" + userLeaving);
1480                mService.updateUsageStats(prev, false);
1481
1482                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
1483                        PauseActivityItem.obtain(prev.finishing, userLeaving,
1484                                prev.configChangeFlags, pauseImmediately)); //相当于执行PauseActivityItem 的excuete
1485            } catch (Exception e) {
1486                // Ignore exception, if process died other code will cleanup.
1487                Slog.w(TAG, "Exception thrown during pause", e);
1488                mPausingActivity = null;
1489                mLastPausedActivity = null;
1490                mLastNoHistoryActivity = null;
1491            }
1492        } else {
1493            mPausingActivity = null;
1494            mLastPausedActivity = null;
1495            mLastNoHistoryActivity = null;
1496        }
1497
1498        // If we are not going to sleep, we want to ensure the device is
1499        // awake until the next activity is started.
1500        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
1501            mStackSupervisor.acquireLaunchWakelock();
1502        }
1503
1504        if (mPausingActivity != null) {
1505            // Have the window manager pause its key dispatching until the new
1506            // activity has started.  If we're pausing the activity just because
1507            // the screen is being turned off and the UI is sleeping, don't interrupt
1508            // key dispatch; the same activity will pick it up again on wakeup.
1509            if (!uiSleeping) {
1510                prev.pauseKeyDispatchingLocked();
1511            } else if (DEBUG_PAUSE) {
1512                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
1513            }
1514
1515            if (pauseImmediately) {
1516                // If the caller said they don't want to wait for the pause, then complete
1517                // the pause now.
1518                completePauseLocked(false, resuming); //立即开始执行 completePauseLocked,并返回false,代表此时要pause的Activity已经不处于pausing状态
                        //因为进入了completePauseLocked立即就会将pausing状态改为paused状态
1519                return false;
1520
1521            } else {
1522                schedulePauseTimeout(prev); 
1523                return true; //此时prev处于pausing状态
1524            }
1525
1526        } else {
1527            // This activity failed to schedule the
1528            // pause, so just treat it as being paused now.
1529            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
1530            if (resuming == null) {
1531                mStackSupervisor.resumeFocusedStackTopActivityLocked();
1532            }
1533            return false;
1534        }
1535    }

pause的相关逻辑

PauseActivityItem

28/**
29 * Request to move an activity to paused state.
30 * @hide
31 */
32public class PauseActivityItem extends ActivityLifecycleItem {
33
34    private static final String TAG = "PauseActivityItem";
35
36    private boolean mFinished;
37    private boolean mUserLeaving;
38    private int mConfigChanges;
39    private boolean mDontReport;
40
41    @Override
42    public void execute(ClientTransactionHandler client, IBinder token,
43            PendingTransactionActions pendingActions) {
44        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
45        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
46                "PAUSE_ACTIVITY_ITEM");
47        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
48    }

ActivityThread#handlePauseActivity

3931    @Override
3932    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
3933            int configChanges, PendingTransactionActions pendingActions, String reason) {
3934        ActivityClientRecord r = mActivities.get(token);
3935        if (r != null) {
3936            if (userLeaving) {
3937                performUserLeavingActivity(r);
3938            }
3939
3940            r.activity.mConfigChangeFlags |= configChanges;
3941            performPauseActivity(r, finished, reason, pendingActions);
3942
3943            // Make sure any pending writes are now committed.
3944            if (r.isPreHoneycomb()) {
3945                QueuedWork.waitToFinish();
3946            }
3947            mSomeActivitiesChanged = true;
3948        }
3949    }

ActivityThread#performPauseActivity

3955    final Bundle performPauseActivity(IBinder token, boolean finished, String reason,
3956            PendingTransactionActions pendingActions) {
3957        ActivityClientRecord r = mActivities.get(token);
3958        return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null;
3959    }
3960
3961    /**
3962     * Pause the activity.
3963     * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
3964     */
3965    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
3966            PendingTransactionActions pendingActions) {
3967        if (r.paused) {
3968            if (r.activity.mFinished) {
3969                // If we are finishing, we won't call onResume() in certain cases.
3970                // So here we likewise don't want to call onPause() if the activity
3971                // isn't resumed.
3972                return null;
3973            }
3974            RuntimeException e = new RuntimeException(
3975                    "Performing pause of activity that is not resumed: "
3976                    + r.intent.getComponent().toShortString());
3977            Slog.e(TAG, e.getMessage(), e);
3978        }
3979        if (finished) {
3980            r.activity.mFinished = true;
3981        }
3982
3983        // Pre-Honeycomb apps always save their state before pausing
3984        final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
3985        if (shouldSaveState) {
3986            callActivityOnSaveInstanceState(r);
3987        }
3988
3989        performPauseActivityIfNeeded(r, reason);
3990
3991        // Notify any outstanding on paused listeners
3992        ArrayList<OnActivityPausedListener> listeners;
3993        synchronized (mOnPauseListeners) {
3994            listeners = mOnPauseListeners.remove(r.activity);
3995        }
3996        int size = (listeners != null ? listeners.size() : 0);
3997        for (int i = 0; i < size; i++) {
3998            listeners.get(i).onPaused(r.activity);
3999        }
4000
4001        final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null;
4002        if (oldState != null) {
4003            // We need to keep around the original state, in case we need to be created again.
4004            // But we only do this for pre-Honeycomb apps, which always save their state when
4005            // pausing, so we can not have them save their state when restarting from a paused
4006            // state. For HC and later, we want to (and can) let the state be saved as the
4007            // normal part of stopping the activity.
4008            if (r.isPreHoneycomb()) {
4009                r.state = oldState;
4010            }
4011        }
4012
4013        return shouldSaveState ? r.state : null;
4014    }
4015
4016    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
4017        if (r.paused) {
4018            // You are already paused silly...
4019            return;
4020        }
4021
4022        try {
4023            r.activity.mCalled = false;
4024            mInstrumentation.callActivityOnPause(r.activity);
4025            if (!r.activity.mCalled) {
4026                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
4027                        + " did not call through to super.onPause()");
4028            }
4029        } catch (SuperNotCalledException e) {
4030            throw e;
4031        } catch (Exception e) {
4032            if (!mInstrumentation.onException(r.activity, e)) {
4033                throw new RuntimeException("Unable to pause activity "
4034                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
4035            }
4036        }
4037        r.setState(ON_PAUSE);
4038    }

ActivityStack#schedulePauseTimeout

1396    /**
1397     * Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
1398     * this directly impacts the responsiveness seen by the user.
1399     */
1400    private void schedulePauseTimeout(ActivityRecord r) {
1401        final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
1402        msg.obj = r;
1403        r.pauseTime = SystemClock.uptimeMillis();
1404        mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
1405        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
1406    }
394        @Override
395        public void handleMessage(Message msg) {
396            switch (msg.what) {
397                case PAUSE_TIMEOUT_MSG: {
398                    ActivityRecord r = (ActivityRecord)msg.obj;
399                    // We don't at this point know if the activity is fullscreen,
400                    // so we need to be conservative and assume it isn't.
401                    Slog.w(TAG, "Activity pause timeout for " + r);
402                    synchronized (mService) {
403                        if (r.app != null) {
404                            mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
405                        }
406                        activityPausedLocked(r.appToken, true); //为true代表真的超时了
407                    }
408                } break;

ActivityManagerService#activityPaused

PauseActivityItem执行完excute之后会执行相应的postExecute

lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
55    @Override
56    public void postExecute(ClientTransactionHandler client, IBinder token,
57            PendingTransactionActions pendingActions) {
58        if (mDontReport) {
59            return;
60        }
61        try {
62            // TODO(lifecycler): Use interface callback instead of AMS.
63            ActivityManager.getService().activityPaused(token); //调用AMS的activityPaused接口
64        } catch (RemoteException ex) {
65            throw ex.rethrowFromSystemServer();
66        }
67    }
8311    @Override
8312    public final void activityPaused(IBinder token) {
8313        final long origId = Binder.clearCallingIdentity();
8314        synchronized(this) {
8315            ActivityStack stack = ActivityRecord.getStackLocked(token);
8316            if (stack != null) {
8317                stack.activityPausedLocked(token, false); //为false代表pause完成 (类似ANR的原理)
8318            }
8319        }
8320        Binder.restoreCallingIdentity(origId);
8321    }

ActivityStack#activityPausedLocked

1537    final void activityPausedLocked(IBinder token, boolean timeout) {
1538        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1539            "Activity paused: token=" + token + ", timeout=" + timeout);
1540
1541        final ActivityRecord r = isInStackLocked(token);
1542        if (r != null) {
1543            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 
               //取消超时消息
1544            if (mPausingActivity == r) {
1545                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
1546                        + (timeout ? " (due to timeout)" : " (pause complete)"));
1547                mService.mWindowManager.deferSurfaceLayout();
1548                try {
1549                    completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
1550                } finally {
1551                    mService.mWindowManager.continueSurfaceLayout();
1552                }
1553                return;
1554            } else {
1555                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
1556                        r.userId, System.identityHashCode(r), r.shortComponentName,
1557                        mPausingActivity != null
1558                            ? mPausingActivity.shortComponentName : "(none)");
1559                if (r.isState(PAUSING)) {
1560                    r.setState(PAUSED, "activityPausedLocked");
1561                    if (r.finishing) {
1562                        if (DEBUG_PAUSE) Slog.v(TAG,
1563                                "Executing finish of failed to pause activity: " + r);
1564                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
1565                                "activityPausedLocked");
1566                    }
1567                }
1568            }
1569        }
1570        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
1571    }

不管是因为Activity onPause执行完了直接回调AMS端的activityPaused,还是因为startPausingLocked中的schedulePauseTimeout发送消息PAUSE_TIMEOUT_MSG(运行在ActivityStackHandler,依附于子线程ActivityMananger)都可能触发completePauseLocked,(如果没超时,那么实在AMS中的binder线程中执行,但如果超时了,那么就会在AMS中的ActivityManager线程中执行)在其中将pausing的Activity的state改为PAUSED状态,并根据情况决定是否结束该Activity;参考一个AMS相关的稳定性问题;然后走要resume的Activity的相关流程;

ActivityStackHandler.png

ActivityStack#completePauseLocked

1573    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
1574        ActivityRecord prev = mPausingActivity;
1575        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
1576
1577        if (prev != null) {
1578            prev.setWillCloseOrEnterPip(false);
1579            final boolean wasStopping = prev.isState(STOPPING);
1580            prev.setState(PAUSED, "completePausedLocked");
1581            if (prev.finishing) {
1582                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
1583                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
1584                        "completedPausedLocked");
1585            } else if (prev.app != null) {
1586                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
1587                        + " wasStopping=" + wasStopping + " visible=" + prev.visible);
1588                if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
1589                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1590                            "Complete pause, no longer waiting: " + prev);
1591                }
1592                if (prev.deferRelaunchUntilPaused) {
1593                    // Complete the deferred relaunch that was waiting for pause to complete.
1594                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
1595                    prev.relaunchActivityLocked(false /* andResume */,
1596                            prev.preserveWindowOnDeferredRelaunch);
1597                } else if (wasStopping) {
1598                    // We are also stopping, the stop request must have gone soon after the pause.
1599                    // We can't clobber it, because the stop confirmation will not be handled.
1600                    // We don't need to schedule another stop, we only need to let it happen.
1601                    prev.setState(STOPPING, "completePausedLocked");
1602                } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
1603                    // Clear out any deferred client hide we might currently have.
1604                    prev.setDeferHidingClient(false);
1605                    // If we were visible then resumeTopActivities will release resources before
1606                    // stopping.
1607                    addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
1608                }
1609            } else {
1610                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
1611                prev = null;
1612            }
1613            // It is possible the activity was freezing the screen before it was paused.
1614            // In that case go ahead and remove the freeze this activity has on the screen
1615            // since it is no longer visible.
1616            if (prev != null) {
1617                prev.stopFreezingScreenLocked(true /*force*/);
1618            }
1619            mPausingActivity = null;
1620        }
1621
1622        if (resumeNext) {
1623            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
1624            if (!topStack.shouldSleepOrShutDownActivities()) {
1625                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); //重新调用resumeFocusedStackTopActivityLocked的逻辑
1626            } else {
1627                checkReadyForSleep();
1628                ActivityRecord top = topStack.topRunningActivityLocked();
1629                if (top == null || (prev != null && top != prev)) {
1630                    // If there are no more activities available to run, do resume anyway to start
1631                    // something. Also if the top activity on the stack is not the just paused
1632                    // activity, we need to go ahead and resume it to ensure we complete an
1633                    // in-flight app switch.
1634                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
1635                }
1636            }
1637        }
1638
1639        if (prev != null) {
1640            prev.resumeKeyDispatchingLocked();
1641
1642            if (prev.app != null && prev.cpuTimeAtResume > 0
1643                    && mService.mBatteryStatsService.isOnBattery()) {
1644                long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
1645                        - prev.cpuTimeAtResume;
1646                if (diff > 0) {
1647                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
1648                    synchronized (bsi) {
1649                        BatteryStatsImpl.Uid.Proc ps =
1650                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
1651                                        prev.info.packageName);
1652                        if (ps != null) {
1653                            ps.addForegroundTimeLocked(diff);
1654                        }
1655                    }
1656                }
1657            }
1658            prev.cpuTimeAtResume = 0; // reset it
1659        }
1660
1661        // Notify when the task stack has changed, but only if visibilities changed (not just
1662        // focus). Also if there is an active pinned stack - we always want to notify it about
1663        // task stack changes, because its positioning may depend on it.
1664        boolean hasPinnedStack = getDisplay() != null && getDisplay().hasPinnedStack();
1665        if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
1666                || hasPinnedStack) {
1667            mService.mTaskChangeNotificationController.notifyTaskStackChanged();
1668            mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
1669        }
1670
1671        mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS); //调整Activity的可见性
1672    }
activityPaused.png

在completePauseLocked之后,上一个resumed Activity已经变成了paused状态,下面重新进行resume的相关操作,会重新走到这里resumeTopActivityInnerLocked,根据是否有复用Activity决定是直接resume,还是创建相关的Activity,再走resume相关逻辑;看第二种情况

 else {
2800            // Whoops, need to restart this activity!
2801            if (!next.hasBeenLaunched) {
2802                next.hasBeenLaunched = true;
2803            } else {
2804                if (SHOW_APP_STARTING_PREVIEW) {
2805                    next.showStartingWindow(null /* prev */, false /* newTask */,
2806                            false /* taskSwich */);
2807                }
2808                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
2809            }
2810            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
2811            mStackSupervisor.startSpecificActivityLocked(next, true, true); //第一次创建时调用startSpecificActivityLocked
2812        }

ActivityStackSupervisor#startSpecificActivityLocked

1692    void startSpecificActivityLocked(ActivityRecord r,
1693            boolean andResume, boolean checkConfig) {
1694        // Is this activity's application already running?
1695        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1696                r.info.applicationInfo.uid, true);
1697
1698        getLaunchTimeTracker().setLaunchTime(r);
1699
1700        if (app != null && app.thread != null) {
            //Activity对应进程已经启动的情况
1701            try {
1702                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1703                        || !"android".equals(r.info.packageName)) {
1704                    // Don't add this if it is a platform component that is marked
1705                    // to run in multiple processes, because this is actually
1706                    // part of the framework so doesn't make sense to track as a
1707                    // separate apk in the process.
1708                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
1709                            mService.mProcessStats);
1710                }
1711                realStartActivityLocked(r, app, andResume, checkConfig);
1712                return;
1713            } catch (RemoteException e) {
1714                Slog.w(TAG, "Exception when starting activity "
1715                        + r.intent.getComponent().flattenToShortString(), e);
1716            }
1717
1718            // If a dead object exception was thrown -- fall through to
1719            // restart the application.
1720        }
1721
1722        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1723                "activity", r.intent.getComponent(), false, false, true);  
            //对应进程未启动,先启动进程,启动后会启动相应的Activity
1724    }

ActivityStackSupervisor# realStartActivityLocked

1384    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
1385            boolean andResume, boolean checkConfig) throws RemoteException {
1386
1387        if (!allPausedActivitiesComplete()) {
1388            // While there are activities pausing we skipping starting any new activities until
1389            // pauses are complete. NOTE: that we also do this for activities that are starting in
1390            // the paused state because they will first be resumed then paused on the client side.
1391            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1392                    "realStartActivityLocked: Skipping start of r=" + r
1393                    + " some activities pausing...");
1394            return false;
1395        }
1396
1397        final TaskRecord task = r.getTask();
1398        final ActivityStack stack = task.getStack();
1399
1400        beginDeferResume();
1401
1402        try {
1403            r.startFreezingScreenLocked(app, 0);
1404
1405            // schedule launch ticks to collect information about slow apps.
1406            r.startLaunchTickingLocked();
1407
1408            r.setProcess(app); //为ActivityRecord设置app属性
1409
1410            if (getKeyguardController().isKeyguardLocked()) {
1411                r.notifyUnknownVisibilityLaunched();
1412            }
1413
1414            // Have the window manager re-evaluate the orientation of the screen based on the new
1415            // activity order.  Note that as a result of this, it can call back into the activity
1416            // manager with a new orientation.  We don't care about that, because the activity is
1417            // not currently running so we are just restarting it anyway.
1418            if (checkConfig) {
1419                // Deferring resume here because we're going to launch new activity shortly.
1420                // We don't want to perform a redundant launch of the same record while ensuring
1421                // configurations and trying to resume top activity of focused stack.
1422                ensureVisibilityAndConfig(r, r.getDisplayId(),
1423                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
1424            }
1425
1426            if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,
1427                    true /* isTop */)) {
1428                // We only set the visibility to true if the activity is allowed to be visible
1429                // based on
1430                // keyguard state. This avoids setting this into motion in window manager that is
1431                // later cancelled due to later calls to ensure visible activities that set
1432                // visibility back to false.
1433                r.setVisibility(true);
1434            }
1435
1436            final int applicationInfoUid =
1437                    (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
1438            if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
1439                Slog.wtf(TAG,
1440                        "User ID for activity changing for " + r
1441                                + " appInfo.uid=" + r.appInfo.uid
1442                                + " info.ai.uid=" + applicationInfoUid
1443                                + " old=" + r.app + " new=" + app);
1444            }
1445
1446            app.waitingToKill = null;
1447            r.launchCount++;
1448            r.lastLaunchTime = SystemClock.uptimeMillis();
1449
1450            if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
1451
1452            int idx = app.activities.indexOf(r);
1453            if (idx < 0) {
1454                app.activities.add(r);
1455            }
1456            mService.updateLruProcessLocked(app, true, null);
1457            mService.updateOomAdjLocked();
1458
1459            final LockTaskController lockTaskController = mService.getLockTaskController();
1460            if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
1461                    || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
1462                    || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED
1463                            && lockTaskController.getLockTaskModeState()
1464                                    == LOCK_TASK_MODE_LOCKED)) {
1465                lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
1466            }
1467
1468            try {
1469                if (app.thread == null) {
1470                    throw new RemoteException();
1471                }
1472                List<ResultInfo> results = null;
1473                List<ReferrerIntent> newIntents = null;
1474                if (andResume) {
1475                    // We don't need to deliver new intents and/or set results if activity is going
1476                    // to pause immediately after launch.
1477                    results = r.results;
1478                    newIntents = r.newIntents;
1479                }
1480                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1481                        "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
1482                                + " newIntents=" + newIntents + " andResume=" + andResume);
1483                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId,
1484                        System.identityHashCode(r), task.taskId, r.shortComponentName);
1485                if (r.isActivityTypeHome()) {
1486                    // Home process is the root process of the task.
1487                    mService.mHomeProcess = task.mActivities.get(0).app;
1488                }
1489                mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
1490                        PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
1491                r.sleeping = false;
1492                r.forceNewConfig = false;
1493                mService.getAppWarningsLocked().onStartActivity(r);
1494                mService.showAskCompatModeDialogLocked(r);
1495                r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1496                ProfilerInfo profilerInfo = null;
1497                if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1498                    if (mService.mProfileProc == null || mService.mProfileProc == app) {
1499                        mService.mProfileProc = app;
1500                        ProfilerInfo profilerInfoSvc = mService.mProfilerInfo;
1501                        if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
1502                            if (profilerInfoSvc.profileFd != null) {
1503                                try {
1504                                    profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
1505                                } catch (IOException e) {
1506                                    profilerInfoSvc.closeFd();
1507                                }
1508                            }
1509
1510                            profilerInfo = new ProfilerInfo(profilerInfoSvc);
1511                        }
1512                    }
1513                }
1514
1515                app.hasShownUi = true;
1516                app.pendingUiClean = true;
1517                app.forceProcessStateUpTo(mService.mTopProcessState);
1518                // Because we could be starting an Activity in the system process this may not go
1519                // across a Binder interface which would create a new Configuration. Consequently
1520                // we have to always create a new Configuration here.
1521
1522                final MergedConfiguration mergedConfiguration = new MergedConfiguration(
1523                        mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
1524                r.setLastReportedConfiguration(mergedConfiguration);
1525
1526                logIfTransactionTooLarge(r.intent, r.icicle);
1527
1528
1529                // Create activity launch transaction.
1530                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
1531                        r.appToken);
1532                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
1533                        System.identityHashCode(r), r.info,
1534                        // TODO: Have this take the merged configuration instead of separate global
1535                        // and override configs.
1536                        mergedConfiguration.getGlobalConfiguration(),
1537                        mergedConfiguration.getOverrideConfiguration(), r.compat,
1538                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
1539                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
1540                        profilerInfo));
1541
1542                // Set desired final state.
1543                final ActivityLifecycleItem lifecycleItem;
1544                if (andResume) {
1545                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
1546                } else {
1547                    lifecycleItem = PauseActivityItem.obtain();
1548                }
1549                clientTransaction.setLifecycleStateRequest(lifecycleItem);
1550
1551                // Schedule transaction.
1552                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
1553
1554
1555                if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
1556                        && mService.mHasHeavyWeightFeature) {
1557                    // This may be a heavy-weight process!  Note that the package
1558                    // manager will ensure that only activity can run in the main
1559                    // process of the .apk, which is the only thing that will be
1560                    // considered heavy-weight.
1561                    if (app.processName.equals(app.info.packageName)) {
1562                        if (mService.mHeavyWeightProcess != null
1563                                && mService.mHeavyWeightProcess != app) {
1564                            Slog.w(TAG, "Starting new heavy weight process " + app
1565                                    + " when already running "
1566                                    + mService.mHeavyWeightProcess);
1567                        }
1568                        mService.mHeavyWeightProcess = app;
1569                        Message msg = mService.mHandler.obtainMessage(
1570                                ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1571                        msg.obj = r;
1572                        mService.mHandler.sendMessage(msg);
1573                    }
1574                }
1575
1576            } catch (RemoteException e) {
1577                if (r.launchFailed) {
1578                    // This is the second time we failed -- finish activity
1579                    // and give up.
1580                    Slog.e(TAG, "Second failure launching "
1581                            + r.intent.getComponent().flattenToShortString()
1582                            + ", giving up", e);
1583                    mService.appDiedLocked(app);
1584                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1585                            "2nd-crash", false);
1586                    return false;
1587                }
1588
1589                // This is the first time we failed -- restart process and
1590                // retry.
1591                r.launchFailed = true;
1592                app.activities.remove(r);
1593                throw e;
1594            }
1595        } finally {
1596            endDeferResume();
1597        }
1598
1599        r.launchFailed = false;
1600        if (stack.updateLRUListLocked(r)) {
1601            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
1602        }
1603
1604        // TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
1605        // so updating the state should be done accordingly.
1606        if (andResume && readyToResume()) {
1607            // As part of the process of launching, ActivityThread also performs
1608            // a resume.
1609            stack.minimalResumeActivityLocked(r);
1610        } else {
1611            // This activity is not starting in the resumed state... which should look like we asked
1612            // it to pause+stop (but remain visible), and it has done so and reported back the
1613            // current icicle and other state.
1614            if (DEBUG_STATES) Slog.v(TAG_STATES,
1615                    "Moving to PAUSED: " + r + " (starting in paused state)");
1616            r.setState(PAUSED, "realStartActivityLocked");
1617        }
1618
1619        // Launch the new version setup screen if needed.  We do this -after-
1620        // launching the initial activity (that is, home), so that it can have
1621        // a chance to initialize itself while in the background, making the
1622        // switch back to it faster and look better.
1623        if (isFocusedStack(stack)) {
1624            mService.getActivityStartController().startSetupActivity();
1625        }
1626
1627        // Update any services we are bound to that might care about whether
1628        // their client may have activities.
1629        if (r.app != null) {
1630            mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
1631        }
1632
1633        return true;
1634    }

走到realStartActivityLocked就开始了真正启动,resume;其为等待start的Activity的逻辑,在下一章中介绍


startActivity.png
上一篇 下一篇

猜你喜欢

热点阅读