How to start next activity if the top activity is stopped/killed
来源:互联网 发布:linux 编辑 grub 编辑:程序博客网 时间:2024/06/03 18:26
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.
1. Back trace
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)
2. How to select next activity
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 ready1557 if (!mService.mBooting && !mService.mBooted) {1558 // Not ready yet!1559 return false;1560 }15611562 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 }15691570 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); 15741575 // Remember how we'll process this pause/resume situation, and ensure1576 // 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 stack1580 final TaskRecord prevTask = prev != null ? prev.task : null;1581 if (next == null) {1582 // There are no more activities! Let's just start up the1583 // 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 display1588 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?1589 HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();1590 return isOnHomeDisplay() &&1591 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");1592 }15931594 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 there1623 // 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 }16311632 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 }16531654 // If we are sleeping, and there is no resumed activity, and the top1655 // activity is paused, well that is the state we want.1656 if (mService.isSleepingOrShuttingDown()1657 && mLastPausedActivity == next1658 && mStackSupervisor.allPausedActivitiesComplete()) {1659 // Make sure we have executed any pending transitions, since there1660 // 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 }16681669 // 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 bringing1671 // 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 " + next1674 + ": user " + next.userId + " is stopped");1675 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();1676 return false;1677 }16781679 // The activity may be waiting for stop, but that is no longer1680 // appropriate for it.1681 mStackSupervisor.mStoppingActivities.remove(next);1682 mStackSupervisor.mGoingToSleepActivities.remove(next);1683 next.sleeping = false;1684 mStackSupervisor.mWaitingVisibleActivities.remove(next);16851686 if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);16871688 // If we are currently pausing an activity, then don't do anything1689 // 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 }17251726 // We need to start pausing the current activity so the top one1727 // 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 process1738 // at the top of the LRU list, since we know we will be needing it1739 // very soon and it would be a waste to let it get killed if it1740 // 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 }17471748 // If the most recent activity was noHistory but was only stopped rather1749 // than stopped+finished because the device went to sleep, we need to make1750 // 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 }17591760 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 previous1768 // 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 mean1770 // it is on top of the one being resumed so hiding it quickly1771 // is good. Otherwise, we want to do the normal route of allowing1772 // the resumed activity to be shown so we can decide if the1773 // previous should actually be hidden depending on whether the1774 // 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 }17891790 // Launching this app's activity, make sure the app is no longer1791 // 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 }18001801 // We are starting up the next activity, so tell the window manager1802 // that the previous one will be hidden soon. This way it can know1803 // 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.task1819 ? AppTransition.TRANSIT_ACTIVITY_CLOSE1820 : 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.task1831 ? AppTransition.TRANSIT_ACTIVITY_OPEN1832 : next.mLaunchTaskBehind1833 ? AppTransition.TRANSIT_TASK_OPEN_BEHIND1834 : 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 }18501851 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 }18611862 ActivityStack lastStack = mStackSupervisor.getLastStack();1863 if (next.app != null && next.app.thread != null) {18711872 if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);18731874 // This activity is now becoming visible.1875 mWindowManager.setAppVisibility(next.appToken, true);18761877 // schedule launch ticks to collect information about slow apps.1878 next.startLaunchTickingLocked();18791880 ActivityRecord lastResumedActivity =1881 lastStack == null ? null :lastStack.mResumedActivity;1882 ActivityState lastState = next.state;18831884 mService.updateCpuStats();18851886 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();18941895 // Have the window manager re-evaluate the orientation of1896 // 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 }19071908 if (notUpdated) {1909 // The configuration update wasn't able to keep the existing1910 // instance of the activity, and instead started a new one.1911 // We should be all done, but let's just make sure our activity1912 // is still at the top and schedule another run if something1913 // weird happened.1914 ActivityRecord nextNext = topRunningActivityLocked(null);1915 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,1916 "Activity config changed during resume: " + next1917 + ", 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 }19301931 try {1932 // Deliver all pending results.1933 ArrayList<ResultInfo> a = 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 " + next1939 + ": " + a);1940 next.app.thread.scheduleSendResult(next.appToken, a);1941 }1942 }19431944 if (next.newIntents != null) {1945 next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);1946 }19471948 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,1949 System.identityHashCode(next), next.task.taskId, next.shortComponentName);19541955 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);19621963 mStackSupervisor.checkReadyForSleepLocked();19641965 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 }19891990 // From this point on, if something goes wrong there is no way1991 // 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 this1997 // 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 }20252026 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();20272034 return true;2035 }
- How to start next activity if the top activity is stopped/killed
- Colored SQL--How to force the AWR to capture a specified SQL even if it is not the top one
- How To Detect If an Application Has Stopped Responding
- How To Detect If an Application Has Stopped Responding
- How To Detect If an Application Has Stopped Responding
- Android How to Check if the App is in Background
- Unable to start activity ComponentInfo
- Unable to start activity ComponentInfo
- Unable to start activity ComponentInfo
- Unable to start activity ComponentInfo
- How to specify the orientation for an activity ?
- How to test if the server is configured well to send email to external accoun
- How to Tell if the I/O of the Database is Slow - 1
- How to Tell if the I/O of the Database is Slow - 2
- Unable to start activity:UnsupportedOperationException: addView(View, LayoutParams) is not supported
- how to make native activity to apk
- Unable to start activity ComponentInfo 解决方法
- Unable to start activity ComponentInfo 解决方法
- 文章标题
- git push和git pull的默认行为
- Lua基础知识点2
- Android获取手机状态和监听手机来电状态
- SipApplicationSession过期时间初探
- How to start next activity if the top activity is stopped/killed
- linphone mediatreamer simple demo 之 录音
- webSocket概念
- 参数方法和非参数方法
- XML语法 XML解析
- 《珠珠图案》设计缘起,运行环境,授权,下载
- 图片上写字
- 二叉树(2)
- 图像语义分割的研究进展(课件PPT)