In Android system, activities are managed with stack/task model.
Sometimes the top activity may stop due to crash, ANR, app OTA, LMK, .... In this situation, AMS have to remove the top activity and start another activity as top.
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3220)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3165)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3043)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1352)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2023)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1547)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1530)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.finishCurrentActivityLocked(ActivityStack.java:2996)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.finishActivityLocked(ActivityStack.java:2924)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStack.forceStopPackageLocked(ActivityStack.java:4091)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityStackSupervisor.forceStopPackageLocked(ActivityStackSupervisor.java:2567)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService.forceStopPackageLocked(ActivityManagerService.java:6228)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService.access$400(ActivityManagerService.java:279)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.am.ActivityManagerService$MainHandler.handleMessage(ActivityManagerService.java:1702)
04-16 18:58:52.646 523 552 W ActivityManager: at android.os.Handler.dispatchMessage(Handler.java:102)
04-16 18:58:52.646 523 552 W ActivityManager: at android.os.Looper.loop(Looper.java:135)
04-16 18:58:52.646 523 552 W ActivityManager: at android.os.HandlerThread.run(HandlerThread.java:61)
04-16 18:58:52.646 523 552 W ActivityManager: at com.android.server.ServiceThread.run(ServiceThread.java:46)
It is implemented in ActivityStack.resumeTopActivityInnerLocked method.
1554 final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { 1555 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); 1556Return if AMS not ready 1557 if (!mService.mBooting && !mService.mBooted) { 1558 // Not ready yet! 1559 return false; 1560 } 1561 1562 ActivityRecord parent = mActivityContainer.mParentActivity; 1563 if ((parent != null && parent.state != ActivityState.RESUMED) || 1564 !mActivityContainer.isAttachedLocked()) { 1565 // Do not resume this stack if its parent is not resumed. 1566 // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st. 1567 return false; 1568 } 1569 1570 cancelInitializingActivities(); 1571Find the next non-finish activity in current stack. Search activity from top task to bottom task. 1572 // Find the first activity that is not finishing. 1573 final ActivityRecord next = topRunningActivityOnStackLocked(null); 1574 1575 // Remember how we'll process this pause/resume situation, and ensure 1576 // that the state is reset however we wind up proceeding. 1577 final boolean userLeaving = mStackSupervisor.mUserLeaving; 1578 mStackSupervisor.mUserLeaving = false; 1579Resume launcher instead if there is no non-finish activity in current stack 1580 final TaskRecord prevTask = prev != null ? prev.task : null; 1581 if (next == null) { 1582 // There are no more activities! Let's just start up the 1583 // Launcher... 1584 ActivityOptions.abort(options); 1585 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home"); 1586 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1587 // Only resume home if on home display 1588 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? 1589 HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); 1590 return isOnHomeDisplay() && 1591 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities"); 1592 } 1593 1594 next.delayedResume = false; 1619 // If the top activity is the resumed one, nothing to do. 1620 if (mResumedActivity == next && next.state == ActivityState.RESUMED && 1621 mStackSupervisor.allResumedActivitiesComplete()) { 1622 // Make sure we have executed any pending transitions, since there 1623 // should be nothing left to do at this point. 1624 mWindowManager.executeAppTransition(); 1625 mNoAnimActivities.clear(); 1626 ActivityOptions.abort(options); 1627 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next); 1628 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1629 return false; 1630 } 1631 1632 final TaskRecord nextTask = next.task; 1633 if (prevTask != null && prevTask.stack == this && 1634 prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) { 1635 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1636 if (prevTask == nextTask) { 1637 prevTask.setFrontOfTask(); 1638 } else if (prevTask != topTask()) { 1639 // This task is going away but it was supposed to return to the home stack. 1640 // Now the task above it has to return to the home task instead. 1641 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; 1642 mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1643 } else if (!isOnHomeDisplay()) { 1644 return false; 1645 } else if (!isHomeStack()){ 1646 if (DEBUG_STATES) Slog.d(TAG, 1647 "resumeTopActivityLocked: Launching home next"); 1648 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? 1649 HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); 1650 return mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished"); 1651 } 1652 } 1653 1654 // If we are sleeping, and there is no resumed activity, and the top 1655 // activity is paused, well that is the state we want. 1656 if (mService.isSleepingOrShuttingDown() 1657 && mLastPausedActivity == next 1658 && mStackSupervisor.allPausedActivitiesComplete()) { 1659 // Make sure we have executed any pending transitions, since there 1660 // should be nothing left to do at this point. 1661 mWindowManager.executeAppTransition(); 1662 mNoAnimActivities.clear(); 1663 ActivityOptions.abort(options); 1664 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused"); 1665 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1666 return false; 1667 } 1668 1669 // Make sure that the user who owns this activity is started. If not, 1670 // we will just leave it as is because someone should be bringing 1671 // another user's activities to the top of the stack. 1672 if (mService.mStartedUsers.get(next.userId) == null) { 1673 Slog.w(TAG, "Skipping resume of top activity " + next 1674 + ": user " + next.userId + " is stopped"); 1675 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1676 return false; 1677 } 1678 1679 // The activity may be waiting for stop, but that is no longer 1680 // appropriate for it. 1681 mStackSupervisor.mStoppingActivities.remove(next); 1682 mStackSupervisor.mGoingToSleepActivities.remove(next); 1683 next.sleeping = false; 1684 mStackSupervisor.mWaitingVisibleActivities.remove(next); 1685 1686 if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next); 1687 1688 // If we are currently pausing an activity, then don't do anything 1689 // until that is done. 1690 if (!mStackSupervisor.allPausedActivitiesComplete()) { 1691 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG, 1692 "resumeTopActivityLocked: Skip resume: some activity pausing."); 1693 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1694 return false; 1695 } 1725 1726 // We need to start pausing the current activity so the top one 1727 // can be resumed... 1728 boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0; 1729 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause); 1730 if (mResumedActivity != null) { 1731 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity); 1732 pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); 1733 } 1734 if (pausing) { 1735 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG, 1736 "resumeTopActivityLocked: Skip resume: need to start pausing"); 1737 // At this point we want to put the upcoming activity's process 1738 // at the top of the LRU list, since we know we will be needing it 1739 // very soon and it would be a waste to let it get killed if it 1740 // happens to be sitting towards the end. 1741 if (next.app != null && next.app.thread != null) { 1742 mService.updateLruProcessLocked(next.app, true, null); 1743 } 1744 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1745 return true; 1746 } 1747 1748 // If the most recent activity was noHistory but was only stopped rather 1749 // than stopped+finished because the device went to sleep, we need to make 1750 // sure to finish it as we're making a new activity topmost. 1751 if (mService.isSleeping() && mLastNoHistoryActivity != null && 1752 !mLastNoHistoryActivity.finishing) { 1753 if (DEBUG_STATES) Slog.d(TAG, "no-history finish of " + mLastNoHistoryActivity + 1754 " on new resume"); 1755 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED, 1756 null, "no-history", false); 1757 mLastNoHistoryActivity = null; 1758 } 1759 1760 if (prev != null && prev != next) { 1761 if (!prev.waitingVisible && next != null && !next.nowVisible) { 1762 prev.waitingVisible = true; 1763 mStackSupervisor.mWaitingVisibleActivities.add(prev); 1764 if (DEBUG_SWITCH) Slog.v( 1765 TAG, "Resuming top, waiting visible to hide: " + prev); 1766 } else { 1767 // The next activity is already visible, so hide the previous 1768 // activity's windows right now so we can show the new one ASAP. 1769 // We only do this if the previous is finishing, which should mean 1770 // it is on top of the one being resumed so hiding it quickly 1771 // is good. Otherwise, we want to do the normal route of allowing 1772 // the resumed activity to be shown so we can decide if the 1773 // previous should actually be hidden depending on whether the 1774 // new one is found to be full-screen or not. 1775 if (prev.finishing) { 1776 mWindowManager.setAppVisibility(prev.appToken, false); 1777 if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: " 1778 + prev + ", waitingVisible=" 1779 + (prev != null ? prev.waitingVisible : null) 1780 + ", nowVisible=" + next.nowVisible); 1781 } else { 1782 if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: " 1783 + prev + ", waitingVisible=" 1784 + (prev != null ? prev.waitingVisible : null) 1785 + ", nowVisible=" + next.nowVisible); 1786 } 1787 } 1788 } 1789 1790 // Launching this app's activity, make sure the app is no longer 1791 // considered stopped. 1792 try { 1793 AppGlobals.getPackageManager().setPackageStoppedState( 1794 next.packageName, false, next.userId); /* TODO: Verify if correct userid */ 1795 } catch (RemoteException e1) { 1796 } catch (IllegalArgumentException e) { 1797 Slog.w(TAG, "Failed trying to unstop package " 1798 + next.packageName + ": " + e); 1799 } 1800 1801 // We are starting up the next activity, so tell the window manager 1802 // that the previous one will be hidden soon. This way it can know 1803 // to ignore it when computing the desired screen orientation. 1804 boolean anim = true; 1810 if (prev != null) { 1811 if (prev.finishing) { 1812 if (DEBUG_TRANSITION) Slog.v(TAG, 1813 "Prepare close transition: prev=" + prev); 1814 if (mNoAnimActivities.contains(prev)) { 1815 anim = false; 1816 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); 1817 } else { 1818 mWindowManager.prepareAppTransition(prev.task == next.task 1819 ? AppTransition.TRANSIT_ACTIVITY_CLOSE 1820 : AppTransition.TRANSIT_TASK_CLOSE, false); 1821 } 1822 mWindowManager.setAppWillBeHidden(prev.appToken); 1823 mWindowManager.setAppVisibility(prev.appToken, false); 1824 } else { 1825 if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev); 1826 if (mNoAnimActivities.contains(next)) { 1827 anim = false; 1828 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); 1829 } else { 1830 mWindowManager.prepareAppTransition(prev.task == next.task 1831 ? AppTransition.TRANSIT_ACTIVITY_OPEN 1832 : next.mLaunchTaskBehind 1833 ? AppTransition.TRANSIT_TASK_OPEN_BEHIND 1834 : AppTransition.TRANSIT_TASK_OPEN, false); 1835 } 1836 } 1841 } else { 1842 if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous"); 1843 if (mNoAnimActivities.contains(next)) { 1844 anim = false; 1845 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); 1846 } else { 1847 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false); 1848 } 1849 } 1850 1851 Bundle resumeAnimOptions = null; 1852 if (anim) { 1853 ActivityOptions opts = next.getOptionsForTargetActivityLocked(); 1854 if (opts != null) { 1855 resumeAnimOptions = opts.toBundle(); 1856 } 1857 next.applyOptionsLocked(); 1858 } else { 1859 next.clearOptionsLocked(); 1860 } 1861 1862 ActivityStack lastStack = mStackSupervisor.getLastStack(); 1863 if (next.app != null && next.app.thread != null) { 1871 1872 if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next); 1873 1874 // This activity is now becoming visible. 1875 mWindowManager.setAppVisibility(next.appToken, true); 1876 1877 // schedule launch ticks to collect information about slow apps. 1878 next.startLaunchTickingLocked(); 1879 1880 ActivityRecord lastResumedActivity = 1881 lastStack == null ? null :lastStack.mResumedActivity; 1882 ActivityState lastState = next.state; 1883 1884 mService.updateCpuStats(); 1885 1886 if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + next + " (in existing)"); 1887 next.state = ActivityState.RESUMED; 1888 mResumedActivity = next; 1889 next.task.touchActiveTime(); 1890 mService.addRecentTaskLocked(next.task); 1891 mService.updateLruProcessLocked(next.app, true, null); 1892 updateLRUListLocked(next); 1893 mService.updateOomAdjLocked(); 1894 1895 // Have the window manager re-evaluate the orientation of 1896 // the screen based on the new activity order. 1897 boolean notUpdated = true; 1898 if (mStackSupervisor.isFrontStack(this)) { 1899 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1900 mService.mConfiguration, 1901 next.mayFreezeScreenLocked(next.app) ? next.appToken : null); 1902 if (config != null) { 1903 next.frozenBeforeDestroy = true; 1904 } 1905 notUpdated = !mService.updateConfigurationLocked(config, next, false, false); 1906 } 1907 1908 if (notUpdated) { 1909 // The configuration update wasn't able to keep the existing 1910 // instance of the activity, and instead started a new one. 1911 // We should be all done, but let's just make sure our activity 1912 // is still at the top and schedule another run if something 1913 // weird happened. 1914 ActivityRecord nextNext = topRunningActivityLocked(null); 1915 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG, 1916 "Activity config changed during resume: " + next 1917 + ", new next: " + nextNext); 1918 if (nextNext != next) { 1919 // Do over! 1920 mStackSupervisor.scheduleResumeTopActivities(); 1921 } 1922 if (mStackSupervisor.reportResumedActivityLocked(next)) { 1923 mNoAnimActivities.clear(); 1924 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1925 return true; 1926 } 1927 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1928 return false; 1929 } 1930 1931 try { 1932 // Deliver all pending results. 1933 ArrayLista = next.results; 1934 if (a != null) { 1935 final int N = a.size(); 1936 if (!next.finishing && N > 0) { 1937 if (DEBUG_RESULTS) Slog.v( 1938 TAG, "Delivering results to " + next 1939 + ": " + a); 1940 next.app.thread.scheduleSendResult(next.appToken, a); 1941 } 1942 } 1943 1944 if (next.newIntents != null) { 1945 next.app.thread.scheduleNewIntent(next.newIntents, next.appToken); 1946 } 1947 1948 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, 1949 System.identityHashCode(next), next.task.taskId, next.shortComponentName); 1954 1955 next.sleeping = false; 1956 mService.showAskCompatModeDialogLocked(next); 1957 next.app.pendingUiClean = true; 1958 next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 1959 next.clearOptionsLocked(); 1960 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, 1961 mService.isNextTransitionForward(), resumeAnimOptions); 1962 1963 mStackSupervisor.checkReadyForSleepLocked(); 1964 1965 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next); 1966 } catch (Exception e) { 1967 // Whoops, need to restart this activity! 1968 if (DEBUG_STATES) Slog.v(TAG, "Resume failed; resetting state to " 1969 + lastState + ": " + next); 1970 next.state = lastState; 1971 if (lastStack != null) { 1972 lastStack.mResumedActivity = lastResumedActivity; 1973 } 1974 Slog.i(TAG, "Restarting because process died: " + next); 1975 if (!next.hasBeenLaunched) { 1976 next.hasBeenLaunched = true; 1977 } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null && 1978 mStackSupervisor.isFrontStack(lastStack)) { 1979 mWindowManager.setAppStartingWindow( 1980 next.appToken, next.packageName, next.theme, 1981 mService.compatibilityInfoForPackageLocked(next.info.applicationInfo), 1982 next.nonLocalizedLabel, next.labelRes, next.icon, next.logo, 1983 next.windowFlags, null, true); 1984 } 1985 mStackSupervisor.startSpecificActivityLocked(next, true, false); 1986 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 1987 return true; 1988 } 1989 1990 // From this point on, if something goes wrong there is no way 1991 // to recover the activity. 1992 try { 1993 next.visible = true; 1994 completeResumeLocked(next); 1995 } catch (Exception e) { 1996 // If any exception gets thrown, toss away this 1997 // activity and try the next one. 1998 Slog.w(TAG, "Exception thrown during resume of " + next, e); 1999 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, 2000 "resume-exception", true); 2001 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2002 return true; 2003 } 2004 next.stopped = false; 2006 } else { 2007 // Whoops, need to restart this activity! 2008 if (!next.hasBeenLaunched) { 2009 next.hasBeenLaunched = true; 2010 } else { 2011 if (SHOW_APP_STARTING_PREVIEW) { 2012 mWindowManager.setAppStartingWindow( 2013 next.appToken, next.packageName, next.theme, 2014 mService.compatibilityInfoForPackageLocked( 2015 next.info.applicationInfo), 2016 next.nonLocalizedLabel, 2017 next.labelRes, next.icon, next.logo, next.windowFlags, 2018 null, true); 2019 } 2020 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next); 2021 } 2022 if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next); 2023 mStackSupervisor.startSpecificActivityLocked(next, true, true); 2024 } 2025 2026 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2027 2034 return true; 2035 }