前言
上一章说到realStartActivityLocked,本章从这里开始梳理相关逻辑
相关流程
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.
//当有新的Activity通过realStartActivityLocked启动时,需要调用ensureVisibilityAndConfig保证Activity的visible属性和config
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 */);
//调用ensureVisibilityAndConfig,保证相关activity的visible属性正确;对于当前visible而现在要设为invisible的Activity,将其加入stopping队列中;
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);
//打印am_restart_activity event log
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)); //添加LaunchActivityItem callback
1541
1542 // Set desired final state.
1543 final ActivityLifecycleItem lifecycleItem;
1544 if (andResume) {
1545 lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
//添加ResumeActivityItem request
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 }
ActivityStackSupervisor#ensureVisibilityAndConfig
1636 /**
1637 * Ensure all activities visibility, update orientation and configuration.
1638 *
1639 * @param starting The currently starting activity or {@code null} if there is none.
1640 * @param displayId The id of the display where operation is executed.
1641 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
1642 * {@code true} if config changed.
1643 * @param deferResume Whether to defer resume while updating config.
1644 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
1645 * because of configuration update.
1646 */
1647 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
1648 boolean markFrozenIfConfigChanged, boolean deferResume) {
1649 // First ensure visibility without updating the config just yet. We need this to know what
1650 // activities are affecting configuration now.
1651 // Passing null here for 'starting' param value, so that visibility of actual starting
1652 // activity will be properly updated.
1653 ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
1654 false /* preserveWindows */, false /* notifyClients */); //visible相关
1655
1656 if (displayId == INVALID_DISPLAY) {
1657 // The caller didn't provide a valid display id, skip updating config.
1658 return true;
1659 }
1660
1661 // Force-update the orientation from the WindowManager, since we need the true configuration
1662 // to send to the client now.
1663 final Configuration config = mWindowManager.updateOrientationFromAppTokens(
1664 getDisplayOverrideConfiguration(displayId),
1665 starting != null && starting.mayFreezeScreenLocked(starting.app)
1666 ? starting.appToken : null,
1667 displayId, true /* forceUpdate */); //config相关
1668 if (starting != null && markFrozenIfConfigChanged && config != null) {
1669 starting.frozenBeforeDestroy = true;
1670 }
1671
1672 // Update the configuration of the activities on the display.
1673 return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
1674 displayId);
1675 }
3764 /**
3765 * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
3766 */
3767 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
3768 boolean preserveWindows, boolean notifyClients) {
3769 getKeyguardController().beginActivityVisibilityUpdate();
3770 try {
3771 // First the front stacks. In case any are not fullscreen and are in front of home.
3772 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3773 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
3774 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
3775 final ActivityStack stack = display.getChildAt(stackNdx);
3776 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
3777 notifyClients);
//针对所有display中的所有stack做ensureActivitiesVisibleLocked处理
3778 }
3779 }
3780 } finally {
3781 getKeyguardController().endActivityVisibilityUpdate();
3782 }
3783 }
ActivityStack#ensureActivitiesVisibleLocked
1862
1863 /**
1864 * Ensure visibility with an option to also update the configuration of visible activities.
1865 * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
1866 * @see ActivityStackSupervisor#ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
1867 */
1868 // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
1869 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
1870 boolean preserveWindows, boolean notifyClients) {
1871 mTopActivityOccludesKeyguard = false;
1872 mTopDismissingKeyguardActivity = null;
1873 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
1874 try {
1875 ActivityRecord top = topRunningActivityLocked();
1876 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
1877 + " configChanges=0x" + Integer.toHexString(configChanges));
1878 if (top != null) {
1879 checkTranslucentActivityWaiting(top);
1880 }
1881
1882 // If the top activity is not fullscreen, then we need to
1883 // make sure any activities under it are now visible.
1884 boolean aboveTop = top != null;
1885 final boolean stackShouldBeVisible = shouldBeVisible(starting); //判断当前stack是否可以visible
1886 boolean behindFullscreenActivity = !stackShouldBeVisible;
1887 boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
1888 && (isInStackLocked(starting) == null);
1889 final boolean isTopNotPinnedStack =
1890 isAttached() && getDisplay().isTopNotPinnedStack(this);
1891 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1892 final TaskRecord task = mTaskHistory.get(taskNdx);
1893 final ArrayList<ActivityRecord> activities = task.mActivities;
1894 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1895 final ActivityRecord r = activities.get(activityNdx);
1896 if (r.finishing) {
1897 continue;
1898 }
1899 final boolean isTop = r == top;
1900 if (aboveTop && !isTop) {
1901 continue;
1902 }
1903 aboveTop = false;
1904
1905 // Check whether activity should be visible without Keyguard influence
1906 final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
1907 behindFullscreenActivity);
1908 r.visibleIgnoringKeyguard = visibleIgnoringKeyguard;
1909
1910 // Now check whether it's really visible depending on Keyguard state.
1911 final boolean reallyVisible = checkKeyguardVisibility(r,
1912 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
//根据keyguard的状态来判断是否当前Activity真的可以可见,当Activity处于下方且上方不透明时,reallyVisible = false;
1913 if (visibleIgnoringKeyguard) {
1914 behindFullscreenActivity = updateBehindFullscreen(!stackShouldBeVisible,
1915 behindFullscreenActivity, r);
1916 }
1917 if (reallyVisible) {
1918 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
1919 + " finishing=" + r.finishing + " state=" + r.getState());
1920 // First: if this is not the current activity being started, make
1921 // sure it matches the current configuration.
1922 if (r != starting && notifyClients) {
1923 r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
1924 true /* ignoreStopState */);
1925 }
1926
1927 if (r.app == null || r.app.thread == null) {
//在finishCurrentActivityLocked中可能会调用到这里,参考https://www.jianshu.com/p/7ef551c40467
1928 if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
1929 resumeNextActivity, r)) {
1930 if (activityNdx >= activities.size()) {
1931 // Record may be removed if its process needs to restart.
1932 activityNdx = activities.size() - 1;
1933 } else {
1934 resumeNextActivity = false;
1935 }
1936 }
1937 } else if (r.visible) {
1938 // If this activity is already visible, then there is nothing to do here.
1939 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1940 "Skipping: already visible at " + r);
1941
1942 if (r.mClientVisibilityDeferred && notifyClients) {
1943 r.makeClientVisible();
1944 }
1945
1946 if (r.handleAlreadyVisible()) {
1947 resumeNextActivity = false;
1948 }
1949 } else {
1950 r.makeVisibleIfNeeded(starting, notifyClients);
//如果判断当前Activity确实可见,调用这里
1951 }
1952 // Aggregate current change flags.
1953 configChanges |= r.configChangeFlags;
1954 } else {
1955 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
1956 + " finishing=" + r.finishing + " state=" + r.getState()
1957 + " stackShouldBeVisible=" + stackShouldBeVisible
1958 + " behindFullscreenActivity=" + behindFullscreenActivity
1959 + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
1960 makeInvisible(r);//reallyVisible为false时调用makeInvisible
1961 }
1962 }
1963 final int windowingMode = getWindowingMode();
1964 if (windowingMode == WINDOWING_MODE_FREEFORM) {
1965 // The visibility of tasks and the activities they contain in freeform stack are
1966 // determined individually unlike other stacks where the visibility or fullscreen
1967 // status of an activity in a previous task affects other.
1968 behindFullscreenActivity = !stackShouldBeVisible;
1969 } else if (isActivityTypeHome()) {
1970 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
1971 + " stackShouldBeVisible=" + stackShouldBeVisible
1972 + " behindFullscreenActivity=" + behindFullscreenActivity);
1973 // No other task in the home stack should be visible behind the home activity.
1974 // Home activities is usually a translucent activity with the wallpaper behind
1975 // them. However, when they don't have the wallpaper behind them, we want to
1976 // show activities in the next application stack behind them vs. another
1977 // task in the home stack like recents.
1978 behindFullscreenActivity = true;
1979 }
1980 }
1981
1982 if (mTranslucentActivityWaiting != null &&
1983 mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
1984 // Nothing is getting drawn or everything was already visible, don't wait for timeout.
1985 notifyActivityDrawnLocked(null);
1986 }
1987 } finally {
1988 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate();
1989 }
1990 }
ActivityStack#shouldBeVisible
/**
* Returns true if the stack should be visible.
*
* @param starting The currently starting activity or null if there is none.
*/
boolean shouldBeVisible(ActivityRecord starting) {
if (!isAttached() || mForceHidden) {
return false;
}
if (mStackSupervisor.isFocusedStack(this)) {
return true; //当前stack为focus时,return true
}
final ActivityRecord top = topRunningActivityLocked();
if (top == null && isInStackLocked(starting) == null && !isTopStackOnDisplay()) {
// Shouldn't be visible if you don't have any running activities, not starting one, and
// not the top stack on display.
return false;
}
//当当前stack不为时,那么就会走到下面
final ActivityDisplay display = getDisplay();
boolean gotSplitScreenStack = false;
boolean gotOpaqueSplitScreenPrimary = false;
boolean gotOpaqueSplitScreenSecondary = false;
final int windowingMode = getWindowingMode();
final boolean isAssistantType = isActivityTypeAssistant();
for (int i = display.getChildCount() - 1; i >= 0; --i) {
final ActivityStack other = display.getChildAt(i); //根据上面的stack的相关属性进行判断,判断下方stack中的Activity是否可见
if (other == this) {
// Should be visible if there is no other stack occluding it.
return true;
}
final int otherWindowingMode = other.getWindowingMode();
if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
// In this case the home stack isn't resizeable even though we are in split-screen
// mode. We still want the primary splitscreen stack to be visible as there will be
// a slight hint of it in the status bar area above the non-resizeable home
// activity. In addition, if the fullscreen assistant is over primary splitscreen
// stack, the stack should still be visible in the background as long as the recents
// animation is running.
final int activityType = other.getActivityType();
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
if (activityType == ACTIVITY_TYPE_HOME
|| (activityType == ACTIVITY_TYPE_ASSISTANT
&& mWindowManager.getRecentsAnimationController() != null)) {
return true;
}
}
if (other.isStackTranslucent(starting)) {
// Can be visible behind a translucent fullscreen stack.
continue;
}
return false;
} else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& !gotOpaqueSplitScreenPrimary) {
gotSplitScreenStack = true;
gotOpaqueSplitScreenPrimary =
!other.isStackTranslucent(starting);
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& gotOpaqueSplitScreenPrimary) {
// Can not be visible behind another opaque stack in split-screen-primary mode.
return false;
}
} else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
&& !gotOpaqueSplitScreenSecondary) {
gotSplitScreenStack = true;
gotOpaqueSplitScreenSecondary =
!other.isStackTranslucent(starting);
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
&& gotOpaqueSplitScreenSecondary) {
// Can not be visible behind another opaque stack in split-screen-secondary mode.
return false;
}
}
if (gotOpaqueSplitScreenPrimary && gotOpaqueSplitScreenSecondary) {
// Can not be visible if we are in split-screen windowing mode and both halves of
// the screen are opaque.
return false;
}
if (isAssistantType && gotSplitScreenStack) {
// Assistant stack can't be visible behind split-screen. In addition to this not
// making sense, it also works around an issue here we boost the z-order of the
// assistant window surfaces in window manager whenever it is visible.
return false;
}
}
// Well, nothing is stopping you from being visible...
return true;
}
ActivityStack#makeVisibleAndRestartIfNeeded
2107 private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
2108 boolean isTop, boolean andResume, ActivityRecord r) {
2109 // We need to make sure the app is running if it's the top, or it is just made visible from
2110 // invisible. If the app is already visible, it must have died while it was visible. In this
2111 // case, we'll show the dead window but will not restart the app. Otherwise we could end up
2112 // thrashing.
2113 if (isTop || !r.visible) {
2114 // This activity needs to be visible, but isn't even running...
2115 // get it started and resume if no other stack in this stack is resumed.
2116 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
2117 if (r != starting) {
2118 r.startFreezingScreenLocked(r.app, configChanges);
2119 }
2120 if (!r.visible || r.mLaunchTaskBehind) {
2121 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
2122 r.setVisible(true);
2123 }
2124 if (r != starting) {
2125 mStackSupervisor.startSpecificActivityLocked(r, andResume, false);
2126 return true;
2127 }
2128 }
2129 return false;
2130 }
ActivityRecord#makeVisibleIfNeeded
1770 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
1771 // This activity is not currently visible, but is running. Tell it to become visible.
1772 if (mState == RESUMED || this == starting) {
1773 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
1774 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
1775 return;
1776 }
1777
1778 // If this activity is paused, tell it to now show its window.
1779 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1780 "Making visible and scheduling visibility: " + this);
1781 final ActivityStack stack = getStack();
1782 try {
1783 if (stack.mTranslucentActivityWaiting != null) {
1784 updateOptionsLocked(returningOptions);
1785 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
1786 }
1787 setVisible(true);
1788 sleeping = false;
1789 app.pendingUiClean = true;
1790 if (reportToClient) {
1791 makeClientVisible();
1792 } else {
1793 mClientVisibilityDeferred = true;
1794 }
1795 // The activity may be waiting for stop, but that is no longer appropriate for it.
1796 mStackSupervisor.mStoppingActivities.remove(this);
1797 mStackSupervisor.mGoingToSleepActivities.remove(this);
1798 } catch (Exception e) {
1799 // Just skip on any failure; we'll make it visible when it next restarts.
1800 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
1801 }
1802 handleAlreadyVisible();
1803 }
1676 // TODO: Look into merging with #setVisibility()
1677 void setVisible(boolean newVisible) {
1678 visible = newVisible;
1679 mDeferHidingClient = !visible && mDeferHidingClient;
1680 setVisibility(visible);
1681 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1682 }
ActivityRecord的visible属性 // does this activity's window need to be shown? 代表Activity是否要显示
1671 void setVisibility(boolean visible) {
//WMS,动画相关的一些东西,后续有时间再学习
1672 mWindowContainerController.setVisibility(visible, mDeferHidingClient);
1673 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
1674 }
makevisible.png
ActivityRecord#makeInvisible
private void makeInvisible(ActivityRecord r) {
if (!r.visible) { //当本来已经visible为false时,直接返回就行了
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
return;
}
// Now for any activities that aren't visible to the user, make sure they no longer are
// keeping the screen frozen.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.getState());
try {
final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
"makeInvisible", true /* beforeStopping */);
// Defer telling the client it is hidden if it can enter Pip and isn't current paused,
// stopped or stopping. This gives it a chance to enter Pip in onPause().
// TODO: There is still a question surrounding activities in multi-window mode that want
// to enter Pip after they are paused, but are still visible. I they should be okay to
// enter Pip in those cases, but not "auto-Pip" which is what this condition covers and
// the current contract for "auto-Pip" is that the app should enter it before onPause
// returns. Just need to confirm this reasoning makes sense.
final boolean deferHidingClient = canEnterPictureInPicture
&& !r.isState(STOPPING, STOPPED, PAUSED);
r.setDeferHidingClient(deferHidingClient);
r.setVisible(false); //setVisible为false
switch (r.getState()) {
case STOPPING:
case STOPPED:
if (r.app != null && r.app.thread != null) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Scheduling invisibility: " + r);
mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
WindowVisibilityItem.obtain(false /* showWindow */));
}
// Reset the flag indicating that an app can enter picture-in-picture once the
// activity is hidden
r.supportsEnterPipOnTaskSwitch = false;
break;
case INITIALIZING:
case RESUMED:
case PAUSING:
case PAUSED:
addToStopping(r, true /* scheduleIdle */,
canEnterPictureInPicture /* idleDelayed */); //当下层Activity的state为上面几个时,调用addToStopping
break;
default:
break;
}
} catch (Exception e) {
// Just skip on any failure; we'll make it visible when it next restarts.
Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
}
}
ActivityStack#addToStopping
void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
mStackSupervisor.mStoppingActivities.add(r);
}
// If we already have a few activities waiting to stop, then give up
// on things going idle and start clearing them out. Or if r is the
// last of activity of the last task the stack will be empty and must
// be cleared immediately.
boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
|| (r.frontOfTask && mTaskHistory.size() <= 1);
if (scheduleIdle || forceIdle) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
+ forceIdle + "immediate=" + !idleDelayed);
if (!idleDelayed) {
mStackSupervisor.scheduleIdleLocked();
} else {
mStackSupervisor.scheduleIdleTimeoutLocked(r);
}
} else {
checkReadyForSleep();
}
}
final void scheduleIdleLocked() {
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
makeInvisible.png
对所有stack执行stack.ensureActivitiesVisibleLocked完成之后
然后继续执行LaunchActivityItem和ResumeActivityItem的excute
LaunchActivityItem#execute
70 @Override
71 public void execute(ClientTransactionHandler client, IBinder token,
72 PendingTransactionActions pendingActions) {
73 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
74 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
75 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
76 mPendingResults, mPendingNewIntents, mIsForward,
77 mProfilerInfo, client);
78 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
79 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
80 }
ActivityThread#handleLaunchActivity
3023 /**
3024 * Extended implementation of activity launch. Used when server requests a launch or relaunch.
3025 */
3026 @Override
3027 public Activity handleLaunchActivity(ActivityClientRecord r,
3028 PendingTransactionActions pendingActions, Intent customIntent) {
3029 // If we are getting ready to gc after going to the background, well
3030 // we are back active so skip it.
3031 unscheduleGcIdler();
3032 mSomeActivitiesChanged = true;
3033
3034 if (r.profilerInfo != null) {
3035 mProfiler.setProfiler(r.profilerInfo);
3036 mProfiler.startProfiling();
3037 }
3038
3039 // Make sure we are running with the most recent config.
3040 handleConfigurationChanged(null, null);
3041
3042 if (localLOGV) Slog.v(
3043 TAG, "Handling launch of " + r);
3044
3045 // Initialize before creating the activity
3046 if (!ThreadedRenderer.sRendererDisabled) {
3047 GraphicsEnvironment.earlyInitEGL();
3048 }
3049 WindowManagerGlobal.initialize();
3050
3051 final Activity a = performLaunchActivity(r, customIntent);
3052
3053 if (a != null) {
3054 r.createdConfig = new Configuration(mConfiguration);
3055 reportSizeConfigurations(r);
3056 if (!r.activity.mFinished && pendingActions != null) {
3057 pendingActions.setOldState(r.state);
3058 pendingActions.setRestoreInstanceState(true);
3059 pendingActions.setCallOnPostCreate(true);
3060 }
3061 } else {
3062 // If there was an error, for any reason, tell the activity manager to stop us.
3063 try {
3064 ActivityManager.getService()
3065 .finishActivity(r.token, Activity.RESULT_CANCELED, null,
3066 Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3067 } catch (RemoteException ex) {
3068 throw ex.rethrowFromSystemServer();
3069 }
3070 }
3071
3072 return a;
3073 }
ActivityThread#performLaunchActivity
2810 /** Core implementation of activity launch. */
2811 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2812 ActivityInfo aInfo = r.activityInfo;
2813 if (r.packageInfo == null) {
2814 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2815 Context.CONTEXT_INCLUDE_CODE);
2816 }
2817
2818 ComponentName component = r.intent.getComponent();
2819 if (component == null) {
2820 component = r.intent.resolveActivity(
2821 mInitialApplication.getPackageManager());
2822 r.intent.setComponent(component);
2823 }
2824
2825 if (r.activityInfo.targetActivity != null) {
2826 component = new ComponentName(r.activityInfo.packageName,
2827 r.activityInfo.targetActivity);
2828 }
2829
2830 ContextImpl appContext = createBaseContextForActivity(r);
2831 Activity activity = null;
2832 try {
2833 java.lang.ClassLoader cl = appContext.getClassLoader();
2834 activity = mInstrumentation.newActivity(
2835 cl, component.getClassName(), r.intent); //创建Activity实例
2836 StrictMode.incrementExpectedActivityCount(activity.getClass());
2837 r.intent.setExtrasClassLoader(cl);
2838 r.intent.prepareToEnterProcess();
2839 if (r.state != null) {
2840 r.state.setClassLoader(cl);
2841 }
2842 } catch (Exception e) {
2843 if (!mInstrumentation.onException(activity, e)) {
2844 throw new RuntimeException(
2845 "Unable to instantiate activity " + component
2846 + ": " + e.toString(), e);
2847 }
2848 }
2849
2850 try {
2851 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//创建一个Application实例
2852
2853 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2854 if (localLOGV) Slog.v(
2855 TAG, r + ": app=" + app
2856 + ", appName=" + app.getPackageName()
2857 + ", pkg=" + r.packageInfo.getPackageName()
2858 + ", comp=" + r.intent.getComponent().toShortString()
2859 + ", dir=" + r.packageInfo.getAppDir());
2860
2861 if (activity != null) {
2862 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2863 Configuration config = new Configuration(mCompatConfiguration);
2864 if (r.overrideConfig != null) {
2865 config.updateFrom(r.overrideConfig);
2866 }
2867 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2868 + r.activityInfo.name + " with config " + config);
2869 Window window = null;
2870 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2871 window = r.mPendingRemoveWindow;
2872 r.mPendingRemoveWindow = null;
2873 r.mPendingRemoveWindowManager = null;
2874 }
2875 appContext.setOuterContext(activity);
2876 activity.attach(appContext, this, getInstrumentation(), r.token,
2877 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2878 r.embeddedID, r.lastNonConfigurationInstances, config,
2879 r.referrer, r.voiceInteractor, window, r.configCallback);
2880
2881 if (customIntent != null) {
2882 activity.mIntent = customIntent;
2883 }
2884 r.lastNonConfigurationInstances = null;
2885 checkAndBlockForNetworkAccess();
2886 activity.mStartedActivity = false;
2887 int theme = r.activityInfo.getThemeResource();
2888 if (theme != 0) {
2889 activity.setTheme(theme);
2890 }
2891
2892 activity.mCalled = false;
2893 if (r.isPersistable()) {
2894 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2895 } else {
2896 mInstrumentation.callActivityOnCreate(activity, r.state);
//调用activity.performCreate,调用onCreate,输出am_on_create_called的event log
2897 }
2898 if (!activity.mCalled) {
2899 throw new SuperNotCalledException(
2900 "Activity " + r.intent.getComponent().toShortString() +
2901 " did not call through to super.onCreate()");
2902 }
2903 r.activity = activity;
2904 }
2905 r.setState(ON_CREATE);
2906
2907 mActivities.put(r.token, r); //在ActivityThread中的mActivities保存ActivityClientRecord
2908
2909 } catch (SuperNotCalledException e) {
2910 throw e;
2911
2912 } catch (Exception e) {
2913 if (!mInstrumentation.onException(activity, e)) {
2914 throw new RuntimeException(
2915 "Unable to start activity " + component
2916 + ": " + e.toString(), e);
2917 }
2918 }
2919
2920 return activity;
2921 }
handleLaunchActivity.png
Application Instance.png
ResumeActivityItem#excute
47 @Override
48 public void execute(ClientTransactionHandler client, IBinder token,
49 PendingTransactionActions pendingActions) {
50 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
51 client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
52 "RESUME_ACTIVITY");
53 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
54 }
ActivityThread#handleResumeActivity
3810 @Override
3811 public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
3812 String reason) {
3813 // If we are getting ready to gc after going to the background, well
3814 // we are back active so skip it.
3815 unscheduleGcIdler();
3816 mSomeActivitiesChanged = true;
3817
3818 // TODO Push resumeArgs into the activity for consideration
3819 final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
//调用onResume,并且打印am_on_resume_called event log
3820 if (r == null) {
3821 // We didn't actually resume the activity, so skipping any follow-up actions.
3822 return;
3823 }
3824
3825 final Activity a = r.activity;
3826
3827 if (localLOGV) {
3828 Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
3829 + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
3830 }
3831
3832 final int forwardBit = isForward
3833 ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3834
3835 // If the window hasn't yet been added to the window manager,
3836 // and this guy didn't finish itself or start another activity,
3837 // then go ahead and add the window.
3838 boolean willBeVisible = !a.mStartedActivity;
3839 if (!willBeVisible) {
3840 try {
3841 willBeVisible = ActivityManager.getService().willActivityBeVisible(
3842 a.getActivityToken());
3843 } catch (RemoteException e) {
3844 throw e.rethrowFromSystemServer();
3845 }
3846 }
3847 if (r.window == null && !a.mFinished && willBeVisible) {
3848 r.window = r.activity.getWindow(); //r.window赋值phoneWindow
3849 View decor = r.window.getDecorView();
3850 decor.setVisibility(View.INVISIBLE);
3851 ViewManager wm = a.getWindowManager();
3852 WindowManager.LayoutParams l = r.window.getAttributes();
3853 a.mDecor = decor;
3854 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3855 l.softInputMode |= forwardBit;
3856 if (r.mPreserveWindow) {
3857 a.mWindowAdded = true;
3858 r.mPreserveWindow = false;
3859 // Normally the ViewRoot sets up callbacks with the Activity
3860 // in addView->ViewRootImpl#setView. If we are instead reusing
3861 // the decor view we have to notify the view root that the
3862 // callbacks may have changed.
3863 ViewRootImpl impl = decor.getViewRootImpl();
3864 if (impl != null) {
3865 impl.notifyChildRebuilt();
3866 }
3867 }
3868 if (a.mVisibleFromClient) {
3869 if (!a.mWindowAdded) {
3870 a.mWindowAdded = true;
3871 wm.addView(decor, l);
3872 } else {
3873 // The activity will get a callback for this {@link LayoutParams} change
3874 // earlier. However, at that time the decor will not be set (this is set
3875 // in this method), so no action will be taken. This call ensures the
3876 // callback occurs with the decor set.
3877 a.onWindowAttributesChanged(l);
3878 }
3879 }
3880
3881 // If the window has already been added, but during resume
3882 // we started another activity, then don't yet make the
3883 // window visible.
3884 } else if (!willBeVisible) {
3885 if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
3886 r.hideForNow = true;
3887 }
3888
3889 // Get rid of anything left hanging around.
3890 cleanUpPendingRemoveWindows(r, false /* force */);
3891
3892 // The window is now visible if it has been added, we are not
3893 // simply finishing, and we are not starting another activity.
3894 if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
3895 if (r.newConfig != null) {
3896 performConfigurationChangedForActivity(r, r.newConfig);
3897 if (DEBUG_CONFIGURATION) {
3898 Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
3899 + r.activity.mCurrentConfig);
3900 }
3901 r.newConfig = null;
3902 }
3903 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
3904 WindowManager.LayoutParams l = r.window.getAttributes();
3905 if ((l.softInputMode
3906 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3907 != forwardBit) {
3908 l.softInputMode = (l.softInputMode
3909 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3910 | forwardBit;
3911 if (r.activity.mVisibleFromClient) {
3912 ViewManager wm = a.getWindowManager();
3913 View decor = r.window.getDecorView();
3914 wm.updateViewLayout(decor, l);
3915 }
3916 }
3917
3918 r.activity.mVisibleFromServer = true;
3919 mNumVisibleActivities++;
3920 if (r.activity.mVisibleFromClient) {
3921 r.activity.makeVisible();
3922 }
3923 }
3924 //一些WMS相关的添加窗口,可见属性的相关操作
3925 r.nextIdle = mNewActivities;
3926 mNewActivities = r;
3927 if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
3928 Looper.myQueue().addIdleHandler(new Idler());
3929 }
ActivityThread#performResumeActivity
3730 /**
3731 * Resume the activity.
3732 * @param token Target activity token.
3733 * @param finalStateRequest Flag indicating if this is part of final state resolution for a
3734 * transaction.
3735 * @param reason Reason for performing the action.
3736 *
3737 * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
3738 */
3739 @VisibleForTesting
3740 public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
3741 String reason) {
3742 final ActivityClientRecord r = mActivities.get(token);
3743 if (localLOGV) {
3744 Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
3745 }
3746 if (r == null || r.activity.mFinished) {
3747 return null;
3748 }
3749 if (r.getLifecycleState() == ON_RESUME) {
3750 if (!finalStateRequest) {
3751 final RuntimeException e = new IllegalStateException(
3752 "Trying to resume activity which is already resumed");
3753 Slog.e(TAG, e.getMessage(), e);
3754 Slog.e(TAG, r.getStateString());
3755 // TODO(lifecycler): A double resume request is possible when an activity
3756 // receives two consequent transactions with relaunch requests and "resumed"
3757 // final state requests and the second relaunch is omitted. We still try to
3758 // handle two resume requests for the final state. For cases other than this
3759 // one, we don't expect it to happen.
3760 }
3761 return null;
3762 }
3763 if (finalStateRequest) {
3764 r.hideForNow = false;
3765 r.activity.mStartedActivity = false;
3766 }
3767 try {
3768 r.activity.onStateNotSaved();
3769 r.activity.mFragments.noteStateNotSaved();
3770 checkAndBlockForNetworkAccess();
3771 if (r.pendingIntents != null) {
3772 deliverNewIntents(r, r.pendingIntents);
3773 r.pendingIntents = null;
3774 }
3775 if (r.pendingResults != null) {
3776 deliverResults(r, r.pendingResults, reason);
3777 r.pendingResults = null;
3778 }
3779 r.activity.performResume(r.startsNotResumed, reason);
3780
3781 r.state = null;
3782 r.persistentState = null;
3783 r.setState(ON_RESUME); //设置mLifecycleState = 3
3784 } catch (Exception e) {
3785 if (!mInstrumentation.onException(r.activity, e)) {
3786 throw new RuntimeException("Unable to resume activity "
3787 + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
3788 }
3789 }
3790 return r;
3791 }
handleResumeActivity.png
LaunchActivityItem和ResumeActivityItem引发EXECUTE_TRANSACTION消息被发送之后,再调用minimalResumeActivityLocked,此时相关消息未必开始执行
ActivityStack#minimalResumeActivityLocked
1260 void minimalResumeActivityLocked(ActivityRecord r) {
1261 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
1262 + " callers=" + Debug.getCallers(5));
1263 r.setState(RESUMED, "minimalResumeActivityLocked");
1264 r.completeResumeLocked();
1265 mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
1266 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
1267 "Launch completed; removing icicle of " + r.icicle);
1268 }
ActivityRecord#completeResumeLocked
/**
* Once we know that we have asked an application to put an activity in the resumed state
* (either by launching it or explicitly telling it), this function updates the rest of our
* state to match that fact.
*/
void completeResumeLocked() {
final boolean wasVisible = visible;
setVisible(true);
if (!wasVisible) {
// Visibility has changed, so take a note of it so we call the TaskStackChangedListener
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
idle = false;
results = null;
newIntents = null;
stopped = false;
if (isActivityTypeHome()) {
ProcessRecord app = task.mActivities.get(0).app;
if (app != null && app != service.mHomeProcess) {
service.mHomeProcess = app;
}
try {
new PreferredAppsTask().execute();
} catch (Exception e) {
Log.v (TAG, "Exception: " + e);
}
}
if (nowVisible) {
// We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
mStackSupervisor.reportActivityVisibleLocked(this);
}
// Schedule an idle timeout in case the app doesn't do it for us.
mStackSupervisor.scheduleIdleTimeoutLocked(this);
//发送一次IDLE_TIMEOUT_MSG消息,正常情况在IDLE_NOW_MSG之后发送;均调用activityIdleInternal,但传递参数不同
//IDLE_TIMEOUT_MSG调用activityIdleInternal时,processPausingActivities = true;
//IDLE_NOW_MSG调用activityIdleInternal时,processPausingActivities = false;
//!注意,这里注释的意思是,正常情况下我们应该等到app端的ActivityThread线程空闲之后
//调用在handleResumeActivity添加的Looper.myQueue().addIdleHandler(new Idler())
//其queueIdle中会调用mStackSupervisor.activityIdleInternalLocked(token, false /*
//fromTimeout */, false /* processPausingActivities */, config);
//但是如果app端一直不空闲呢?我们在这里在做个超时机制的判断,如果一段时间后
//activityIdleInternalLocked还未执行,我们就通过IDLE_TIMEOUT_MSG开始执行activityIdleInternalLocked
mStackSupervisor.reportResumedActivityLocked(this);
resumeKeyDispatchingLocked();
final ActivityStack stack = getStack();
mStackSupervisor.mNoAnimActivities.clear();
// Mark the point when the activity is resuming
// TODO: To be more accurate, the mark should be before the onCreate,
// not after the onResume. But for subsequent starts, onResume is fine.
if (app != null) {
cpuTimeAtResume = service.mProcessCpuTracker.getCpuTimeForPid(app.pid);
} else {
cpuTimeAtResume = 0; // Couldn't get the cpu time of process
}
returningOptions = null;
if (canTurnScreenOn()) {
mStackSupervisor.wakeUp("turnScreenOnFlag");
} else {
// If the screen is going to turn on because the caller explicitly requested it and
// the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
// pause and then resume again later, which will result in a double life-cycle event.
stack.checkReadyForSleep();
}
}
ActivityStackSupervisor#reportResumedActivityLocked
boolean reportResumedActivityLocked(ActivityRecord r) {
// A resumed activity cannot be stopping. remove from list
mStoppingActivities.remove(r);
final ActivityStack stack = r.getStack();
if (isFocusedStack(stack)) {
mService.updateUsageStats(r, true);
}
if (allResumedActivitiesComplete()) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); //再做一遍visible的设置
mWindowManager.executeAppTransition();
return true;
}
return false;
}
activityIdleInternal调用的目前理解
activityIdleInternal中有三重保护:
- addToStopping->scheduleIdleLocked->IDLE_NOW_MSG,IDLE_NOW_MSG消息被处理时会调用到activityIdleInternal;看其注释
// If we already have a few activities waiting to stop, then give up
// on things going idle and start clearing them out. Or if r is the
// last of activity of the last task the stack will be empty and must
// be cleared immediately.
就是说当前已经有一些activity待stop了,就不用等待idle到来了;或者当前待stop的activity是一个stack的最后一个actiivty,直接进行清除操作
2.当待启动的Activity变为IdleActivity时,即app的ActivityThread为idle状态,通过binder call调用activityIdleInternal
IdleActivity.png
可以看到通过binder call来调用activityIdleInternalLocked,此时IDLE_NOW_MSG(101)消息还在队列中没有被执行
- completeResumeLocked中的scheduleIdleTimeoutLocked在做一层保险,万一前面都没有执行,那么这里有一个超时机制,保证调用到activityIdleInternal,看其注释
Schedule an idle timeout in case the app doesn't do it for us.
发送一次IDLE_TIMEOUT_MSG消息
IDLE_TIMEOUT_MSG调用activityIdleInternal时,processPausingActivities = true;
IDLE_NOW_MSG调用activityIdleInternal时,processPausingActivities = false;
注意,这里注释的意思是,正常情况下我们应该等到app端的ActivityThread线程空闲之后,调用在handleResumeActivity添加的Looper.myQueue().addIdleHandler(new Idler()),其queueIdle中会调用
mStackSupervisor.activityIdleInternalLocked(token, false /*
fromTimeout */, false /* processPausingActivities */, config);
但是如果app端一直不空闲呢?我们在这里在做个超时机制的判断,如果一段时间后
activityIdleInternalLocked还未执行,我们就通过IDLE_TIMEOUT_MSG开始执行activityIdleInternalLocked
当通过消息调用到activityIdleInternalLocked时,其token参数为null
在下一章中阐述activityIdleInternal的相关逻辑
startActivity.png
网友评论