美文网首页android之AMS学习攻克
Activity相关学习-启动(6)-resumeTopActi

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

作者: weiinter105 | 来源:发表于2019-01-13 22:59 被阅读0次

    前言

    本周重点介绍上章末尾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

    相关文章

      网友评论

        本文标题:Activity相关学习-启动(6)-resumeTopActi

        本文链接:https://www.haomeiwen.com/subject/zphrdqtx.html