本文共 22609 字,大约阅读时间需要 75 分钟。
上文插了一段Activity所在进程没有启动的情况
一:postExecute调用远端
下面继续看Activity启动过程,之前第四篇讲到Activity的pause
之前在TransactionExecutor类中讲到
lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
其中第一个方法是执行本地的onPause方法
尔当运行到第二个方法的时候,其实pause的一系列操作已经做完了
看下poseExecute方法
@Override public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { if (mDontReport) { return; } try { // TODO(lifecycler): Use interface callback instead of AMS. ActivityManager.getService().activityPaused(token); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }
这里其实又来了一次跨进程,这是9.0版本和其他版本的不同之处,
其他版本的通知远端pause已经完成都是在handlePauseActivity中完成的。
二.再次来到AMS
看下ams的activityPaused方法
@Override public final void activityPaused(IBinder token) { final long origId = Binder.clearCallingIdentity(); synchronized(this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { stack.activityPausedLocked(token, false); } } Binder.restoreCallingIdentity(origId); }
然后来到ActivityStack类中的activityPausedLocked方法
final void activityPausedLocked(IBinder token, boolean timeout) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity paused: token=" + token + ", timeout=" + timeout); final ActivityRecord r = isInStackLocked(token); if (r != null) { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); if (mPausingActivity == r) { if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); mService.mWindowManager.deferSurfaceLayout(); try { completePauseLocked(true /* resumeNext */, null /* resumingActivity */); } finally { mService.mWindowManager.continueSurfaceLayout(); } return; } else { EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, r.userId, System.identityHashCode(r), r.shortComponentName, mPausingActivity != null ? mPausingActivity.shortComponentName : "(none)"); if (r.isState(PAUSING)) { r.setState(PAUSED, "activityPausedLocked"); if (r.finishing) { if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of failed to pause activity: " + r); finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false, "activityPausedLocked"); } } } } mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); }
接着调用completePauseLockd方法
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { ActivityRecord prev = mPausingActivity; if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); if (prev != null) { prev.setWillCloseOrEnterPip(false); final boolean wasStopping = prev.isState(STOPPING); prev.setState(PAUSED, "completePausedLocked"); if (prev.finishing) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false, "completedPausedLocked"); } else if (prev.app != null) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev + " wasStopping=" + wasStopping + " visible=" + prev.visible); if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) { if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause, no longer waiting: " + prev); } if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); prev.relaunchActivityLocked(false /* andResume */, prev.preserveWindowOnDeferredRelaunch); } else if (wasStopping) { // We are also stopping, the stop request must have gone soon after the pause. // We can't clobber it, because the stop confirmation will not be handled. // We don't need to schedule another stop, we only need to let it happen. prev.setState(STOPPING, "completePausedLocked"); } else if (!prev.visible || shouldSleepOrShutDownActivities()) { // Clear out any deferred client hide we might currently have. prev.setDeferHidingClient(false); // If we were visible then resumeTopActivities will release resources before // stopping. addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */); } } else { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); prev = null; } // It is possible the activity was freezing the screen before it was paused. // In that case go ahead and remove the freeze this activity has on the screen // since it is no longer visible. if (prev != null) { prev.stopFreezingScreenLocked(true /*force*/); } mPausingActivity = null; } if (resumeNext) { final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!topStack.shouldSleepOrShutDownActivities()) { mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); } else { checkReadyForSleep(); ActivityRecord top = topStack.topRunningActivityLocked(); if (top == null || (prev != null && top != prev)) { // If there are no more activities available to run, do resume anyway to start // something. Also if the top activity on the stack is not the just paused // activity, we need to go ahead and resume it to ensure we complete an // in-flight app switch. mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } } if (prev != null) { prev.resumeKeyDispatchingLocked(); if (prev.app != null && prev.cpuTimeAtResume > 0 && mService.mBatteryStatsService.isOnBattery()) { long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; if (diff > 0) { BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics(); synchronized (bsi) { BatteryStatsImpl.Uid.Proc ps = bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, prev.info.packageName); if (ps != null) { ps.addForegroundTimeLocked(diff); } } } } prev.cpuTimeAtResume = 0; // reset it } // Notify when the task stack has changed, but only if visibilities changed (not just // focus). Also if there is an active pinned stack - we always want to notify it about // task stack changes, because its positioning may depend on it. if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause || getDisplay().hasPinnedStack()) { mService.mTaskChangeNotificationController.notifyTaskStackChanged(); mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; } mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS); }
三:再次调用resumeFocusedStackTopActivityLocked
这里再次调用了、
mStackSupervisor.resumeFocusedStackTopActivityLocked();
然后接着是ActivityStack的
resumeTopActivityUncheckedLocked
resumeTopActivityInnerLocked
这次在这里会执行(之前是startPausingLocked)
ActivityStackSupervisor的startSpecificActivityLocked 方法
然后是realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { if (!allPausedActivitiesComplete()) { // While there are activities pausing we skipping starting any new activities until // pauses are complete. NOTE: that we also do this for activities that are starting in // the paused state because they will first be resumed then paused on the client side. if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, "realStartActivityLocked: Skipping start of r=" + r + " some activities pausing..."); return false; } final TaskRecord task = r.getTask(); final ActivityStack stack = task.getStack(); beginDeferResume(); try { r.startFreezingScreenLocked(app, 0); // schedule launch ticks to collect information about slow apps. r.startLaunchTickingLocked(); r.setProcess(app); if (getKeyguardController().isKeyguardLocked()) { r.notifyUnknownVisibilityLaunched(); } // Have the window manager re-evaluate the orientation of the screen based on the new // activity order. Note that as a result of this, it can call back into the activity // manager with a new orientation. We don't care about that, because the activity is // not currently running so we are just restarting it anyway. if (checkConfig) { // Deferring resume here because we're going to launch new activity shortly. // We don't want to perform a redundant launch of the same record while ensuring // configurations and trying to resume top activity of focused stack. ensureVisibilityAndConfig(r, r.getDisplayId(), false /* markFrozenIfConfigChanged */, true /* deferResume */); } if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, true /* isTop */)) { // We only set the visibility to true if the activity is allowed to be visible // based on // keyguard state. This avoids setting this into motion in window manager that is // later cancelled due to later calls to ensure visible activities that set // visibility back to false. r.setVisibility(true); } final int applicationInfoUid = (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1; if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) { Slog.wtf(TAG, "User ID for activity changing for " + r + " appInfo.uid=" + r.appInfo.uid + " info.ai.uid=" + applicationInfoUid + " old=" + r.app + " new=" + app); } app.waitingToKill = null; r.launchCount++; r.lastLaunchTime = SystemClock.uptimeMillis(); if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); int idx = app.activities.indexOf(r); if (idx < 0) { app.activities.add(r); } mService.updateLruProcessLocked(app, true, null); mService.updateOomAdjLocked(); final LockTaskController lockTaskController = mService.getLockTaskController(); if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED && lockTaskController.getLockTaskModeState() == LOCK_TASK_MODE_LOCKED)) { lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */); } try { if (app.thread == null) { throw new RemoteException(); } Listresults = null; List newIntents = null; if (andResume) { // We don't need to deliver new intents and/or set results if activity is going // to pause immediately after launch. results = r.results; newIntents = r.newIntents; } if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Launching: " + r + " icicle=" + r.icicle + " with results=" + results + " newIntents=" + newIntents + " andResume=" + andResume); EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId, System.identityHashCode(r), task.taskId, r.shortComponentName); if (r.isActivityTypeHome()) { // Home process is the root process of the task. mService.mHomeProcess = task.mActivities.get(0).app; } mService.notifyPackageUse(r.intent.getComponent().getPackageName(), PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY); r.sleeping = false; r.forceNewConfig = false; mService.getAppWarningsLocked().onStartActivity(r); mService.showAskCompatModeDialogLocked(r); r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); ProfilerInfo profilerInfo = null; if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { if (mService.mProfileProc == null || mService.mProfileProc == app) { mService.mProfileProc = app; ProfilerInfo profilerInfoSvc = mService.mProfilerInfo; if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) { if (profilerInfoSvc.profileFd != null) { try { profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup(); } catch (IOException e) { profilerInfoSvc.closeFd(); } } profilerInfo = new ProfilerInfo(profilerInfoSvc); } } } app.hasShownUi = true; app.pendingUiClean = true; app.forceProcessStateUpTo(mService.mTopProcessState); // Because we could be starting an Activity in the system process this may not go // across a Binder interface which would create a new Configuration. Consequently // we have to always create a new Configuration here. final MergedConfiguration mergedConfiguration = new MergedConfiguration( mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration()); r.setLastReportedConfiguration(mergedConfiguration); logIfTransactionTooLarge(r.intent, r.icicle); // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global // and override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. mService.getLifecycleManager().scheduleTransaction(clientTransaction); if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 && mService.mHasHeavyWeightFeature) { // This may be a heavy-weight process! Note that the package // manager will ensure that only activity can run in the main // process of the .apk, which is the only thing that will be // considered heavy-weight. if (app.processName.equals(app.info.packageName)) { if (mService.mHeavyWeightProcess != null && mService.mHeavyWeightProcess != app) { Slog.w(TAG, "Starting new heavy weight process " + app + " when already running " + mService.mHeavyWeightProcess); } mService.mHeavyWeightProcess = app; Message msg = mService.mHandler.obtainMessage( ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); msg.obj = r; mService.mHandler.sendMessage(msg); } } } catch (RemoteException e) { if (r.launchFailed) { // This is the second time we failed -- finish activity // and give up. Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e); mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } // This is the first time we failed -- restart process and // retry. r.launchFailed = true; app.activities.remove(r); throw e; } } finally { endDeferResume(); } r.launchFailed = false; if (stack.updateLRUListLocked(r)) { Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); } // TODO(lifecycler): Resume or pause requests are done as part of launch transaction, // so updating the state should be done accordingly. if (andResume && readyToResume()) { // As part of the process of launching, ActivityThread also performs // a resume. stack.minimalResumeActivityLocked(r); } else { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the // current icicle and other state. if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r + " (starting in paused state)"); r.setState(PAUSED, "realStartActivityLocked"); } // Launch the new version setup screen if needed. We do this -after- // launching the initial activity (that is, home), so that it can have // a chance to initialize itself while in the background, making the // switch back to it faster and look better. if (isFocusedStack(stack)) { mService.getActivityStartController().startSetupActivity(); } // Update any services we are bound to that might care about whether // their client may have activities. if (r.app != null) { mService.mServices.updateServiceConnectionActivitiesLocked(r.app); } return true; }
这部分的关键方法在这里:
// Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global // and override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. mService.getLifecycleManager().scheduleTransaction(clientTransaction);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);到这里,远端的代码执行完了,下面又要再次回到本地转载地址:https://blog.csdn.net/perfectnihil/article/details/91045773 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!