本文共 22827 字,大约阅读时间需要 76 分钟。
在ActivityThread的handleResumeActivity中,最后一行
一:从handleResumeActivity到Idler
@Override public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; // TODO Push resumeArgs into the activity for consideration final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); if (r == null) { // We didn't actually resume the activity, so skipping any follow-up actions. return; } final Activity a = r.activity; if (localLOGV) { Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); } final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; // If the window hasn't yet been added to the window manager, // and this guy didn't finish itself or start another activity, // then go ahead and add the window. boolean willBeVisible = !a.mStartedActivity; if (!willBeVisible) { try { willBeVisible = ActivityManager.getService().willActivityBeVisible( a.getActivityToken()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (r.mPreserveWindow) { a.mWindowAdded = true; r.mPreserveWindow = false; // Normally the ViewRoot sets up callbacks with the Activity // in addView->ViewRootImpl#setView. If we are instead reusing // the decor view we have to notify the view root that the // callbacks may have changed. ViewRootImpl impl = decor.getViewRootImpl(); if (impl != null) { impl.notifyChildRebuilt(); } } if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true; wm.addView(decor, l); } else { // The activity will get a callback for this {@link LayoutParams} change // earlier. However, at that time the decor will not be set (this is set // in this method), so no action will be taken. This call ensures the // callback occurs with the decor set. a.onWindowAttributesChanged(l); } } // If the window has already been added, but during resume // we started another activity, then don't yet make the // window visible. } else if (!willBeVisible) { if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set"); r.hideForNow = true; } // Get rid of anything left hanging around. cleanUpPendingRemoveWindows(r, false /* force */); // The window is now visible if it has been added, we are not // simply finishing, and we are not starting another activity. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { performConfigurationChangedForActivity(r, r.newConfig); if (DEBUG_CONFIGURATION) { Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); } r.newConfig = null; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); WindowManager.LayoutParams l = r.window.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) { l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; if (r.activity.mVisibleFromClient) { ViewManager wm = a.getWindowManager(); View decor = r.window.getDecorView(); wm.updateViewLayout(decor, l); } } r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); } } r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); }
Looper.myQueue().addIdleHandler(new Idler());
看下Idler这个类
private class Idler implements MessageQueue.IdleHandler { @Override public final boolean queueIdle() { ActivityClientRecord a = mNewActivities; boolean stopProfiling = false; if (mBoundApplication != null && mProfiler.profileFd != null && mProfiler.autoStopProfiler) { stopProfiling = true; } if (a != null) { mNewActivities = null; IActivityManager am = ActivityManager.getService(); ActivityClientRecord prev; do { if (localLOGV) Slog.v( TAG, "Reporting idle of " + a + " finished=" + (a.activity != null && a.activity.mFinished)); if (a.activity != null && !a.activity.mFinished) { try { am.activityIdle(a.token, a.createdConfig, stopProfiling); a.createdConfig = null; } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } prev = a; a = a.nextIdle; prev.nextIdle = null; } while (a != null); } if (stopProfiling) { mProfiler.stopProfiling(); } ensureJitEnabled(); return false; } }
二 到远端activityIdle
点am.activityIdle ,这个其实在ActivityManagerService中
@Override public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { final long origId = Binder.clearCallingIdentity(); synchronized (this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */, false /* processPausingActivities */, config); if (stopProfiling) { if ((mProfileProc == r.app) && mProfilerInfo != null) { clearProfilerLocked(); } } } } Binder.restoreCallingIdentity(origId); }
三 ActivityStackSupervisor 的 activityIdleInternalLocked
// Checked. @GuardedBy("mService") final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, boolean processPausingActivities, Configuration config) { if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); ArrayListfinishes = null; ArrayList startingUsers = null; int NS = 0; int NF = 0; boolean booting = false; boolean activityRemoved = false; ActivityRecord r = ActivityRecord.forTokenLocked(token); if (r != null) { if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" + Debug.getCallers(4)); mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); r.finishLaunchTickingLocked(); if (fromTimeout) { reportActivityLaunchedLocked(fromTimeout, r, -1, -1); } // This is a hack to semi-deal with a race condition // in the client where it can be constructed with a // newer configuration from when we asked it to launch. // We'll update with whatever configuration it now says // it used to launch. if (config != null) { r.setLastReportedGlobalConfiguration(config); } // We are now idle. If someone is waiting for a thumbnail from // us, we can now deliver. r.idle = true; //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); if (isFocusedStack(r.getStack()) || fromTimeout) { booting = checkFinishBootingLocked(); } } if (allResumedActivitiesIdle()) { if (r != null) { mService.scheduleAppGcsLocked(); } if (mLaunchingActivity.isHeld()) { mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { throw new IllegalStateException("Calling must be system uid"); } mLaunchingActivity.release(); } ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); } // Atomically retrieve all of the other things to do. final ArrayList stops = processStoppingActivitiesLocked(r, true /* remove */, processPausingActivities); NS = stops != null ? stops.size() : 0; if ((NF = mFinishingActivities.size()) > 0) { finishes = new ArrayList<>(mFinishingActivities); mFinishingActivities.clear(); } if (mStartingUsers.size() > 0) { startingUsers = new ArrayList<>(mStartingUsers); mStartingUsers.clear(); } // Stop any activities that are scheduled to do so but have been // waiting for the next one to start. for (int i = 0; i < NS; i++) { r = stops.get(i); final ActivityStack stack = r.getStack(); if (stack != null) { if (r.finishing) { stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false, "activityIdleInternalLocked"); } else { stack.stopActivityLocked(r); } } } // Finish any activities that are scheduled to do so but have been // waiting for the next one to start. for (int i = 0; i < NF; i++) { r = finishes.get(i); final ActivityStack stack = r.getStack(); if (stack != null) { activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); } } if (!booting) { // Complete user switch if (startingUsers != null) { for (int i = 0; i < startingUsers.size(); i++) { mService.mUserController.finishUserSwitch(startingUsers.get(i)); } } } mService.trimApplications(); //dump(); //mWindowManager.dump(); if (activityRemoved) { resumeFocusedStackTopActivityLocked(); } return r; }
四:ActivityStack 的stopActivityLocked
final void stopActivityLocked(ActivityRecord r) { if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r); if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { if (!r.finishing) { if (!shouldSleepActivities()) { if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r); if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "stop-no-history", false)) { // If {@link requestFinishActivityLocked} returns {@code true}, // {@link adjustFocusedActivityStack} would have been already called. r.resumeKeyDispatchingLocked(); return; } } else { if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r + " on stop because we're just sleeping"); } } } if (r.app != null && r.app.thread != null) { adjustFocusedActivityStack(r, "stopActivity"); r.resumeKeyDispatchingLocked(); try { r.stopped = false; if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPING: " + r + " (stop requested)"); r.setState(STOPPING, "stopActivityLocked"); if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Stopping visible=" + r.visible + " for " + r); if (!r.visible) { r.setVisible(false); } EventLogTags.writeAmStopActivity( r.userId, System.identityHashCode(r), r.shortComponentName); mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, StopActivityItem.obtain(r.visible, r.configChangeFlags)); if (shouldSleepOrShutDownActivities()) { r.setSleeping(true); } Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r); mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); } catch (Exception e) { // Maybe just ignore exceptions here... if the process // has crashed, our death notification will clean things // up. Slog.w(TAG, "Exception thrown during pause", e); // Just in case, assume it to be stopped. r.stopped = true; if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r); r.setState(STOPPED, "stopActivityLocked"); if (r.deferRelaunchUntilPaused) { destroyActivityLocked(r, true, "stop-except"); } } } }
五:StopActivityItem
mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
StopActivityItem.obtain(r.visible, r.configChangeFlags));这样有来到了一个item,StopActivityItem
看下StopActivityItem的execute方法
@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions, true /* finalStateRequest */, "STOP_ACTIVITY_ITEM"); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }
最终还是调到了远端的handleStopActivity方法。
六:ActivityThread的handleStopActivity方法
@Override public void handleStopActivity(IBinder token, boolean show, int configChanges, PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) { final ActivityClientRecord r = mActivities.get(token); r.activity.mConfigChangeFlags |= configChanges; final StopInfo stopInfo = new StopInfo(); performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest, reason); if (localLOGV) Slog.v( TAG, "Finishing stop of " + r + ": show=" + show + " win=" + r.window); updateVisibility(r, show); // Make sure any pending writes are now committed. if (!r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } stopInfo.setActivity(r); stopInfo.setState(r.state); stopInfo.setPersistentState(r.persistentState); pendingActions.setStopInfo(stopInfo); mSomeActivitiesChanged = true; }
performStopActivityInner
/** * Core implementation of stopping an activity. Note this is a little * tricky because the server's meaning of stop is slightly different * than our client -- for the server, stop means to save state and give * it the result when it is done, but the window may still be visible. * For the client, we want to call onStop()/onStart() to indicate when * the activity's UI visibility changes. * @param r Target activity client record. * @param info Action that will report activity stop to server. * @param keepShown Flag indicating whether the activity is still shown. * @param saveState Flag indicating whether the activity state should be saved. * @param finalStateRequest Flag indicating if this call is handling final lifecycle state * request for a transaction. * @param reason Reason for performing this operation. */ private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown, boolean saveState, boolean finalStateRequest, String reason) { if (localLOGV) Slog.v(TAG, "Performing stop of " + r); if (r != null) { if (!keepShown && r.stopped) { if (r.activity.mFinished) { // If we are finishing, we won't call onResume() in certain // cases. So here we likewise don't want to call onStop() // if the activity isn't resumed. return; } if (!finalStateRequest) { final RuntimeException e = new RuntimeException( "Performing stop of activity that is already stopped: " + r.intent.getComponent().toShortString()); Slog.e(TAG, e.getMessage(), e); Slog.e(TAG, r.getStateString()); } } // One must first be paused before stopped... performPauseActivityIfNeeded(r, reason); if (info != null) { try { // First create a thumbnail for the activity... // For now, don't create the thumbnail here; we are // doing that by doing a screen snapshot. info.setDescription(r.activity.onCreateDescription()); } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to save state of activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } } if (!keepShown) { callActivityOnStop(r, saveState, reason); } } }
callActivityOnstop
/** * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates * the client record's state. * All calls to stop an activity must be done through this method to make sure that * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call. */ private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) { // Before P onSaveInstanceState was called before onStop, starting with P it's // called after. Before Honeycomb state was always saved before onPause. final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null && !r.isPreHoneycomb(); final boolean isPreP = r.isPreP(); if (shouldSaveState && isPreP) { callActivityOnSaveInstanceState(r); } try { r.activity.performStop(false /*preserveWindow*/, reason); } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to stop activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } r.setState(ON_STOP); if (shouldSaveState && !isPreP) { callActivityOnSaveInstanceState(r); } }
进入activity的performStop
final void performStop(boolean preserveWindow, String reason) { mDoReportFullyDrawn = false; mFragments.doLoaderStop(mChangingConfigurations /*retain*/); // Disallow entering picture-in-picture after the activity has been stopped mCanEnterPictureInPicture = false; if (!mStopped) { if (mWindow != null) { mWindow.closeAllPanels(); } // If we're preserving the window, don't setStoppedState to true, since we // need the window started immediately again. Stopping the window will // destroys hardware resources and causes flicker. if (!preserveWindow && mToken != null && mParent == null) { WindowManagerGlobal.getInstance().setStoppedState(mToken, true); } mFragments.dispatchStop(); mCalled = false; mInstrumentation.callActivityOnStop(this); writeEventLog(LOG_AM_ON_STOP_CALLED, reason); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onStop()"); } synchronized (mManagedCursors) { final int N = mManagedCursors.size(); for (int i=0; i
mInstrumentation.callActivityOnStop(this);
/** * Perform calling of an activity's {@link Activity#onStop} * method. The default implementation simply calls through to that method. * * @param activity The activity being stopped. */ public void callActivityOnStop(Activity activity) { activity.onStop(); }
最终终于调用到了activity的onStop方法。。
=====================================================
Activity启动流程终于过完了.......好复杂。。。
转载地址:https://blog.csdn.net/perfectnihil/article/details/91049474 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!