ActivityStack.startPausingLocked()
IApplicationThread.schudulePauseActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage();
ActivityThread.H.handleMessage()
ActivityThread.handlePauseActivity()
ActivityThread.performPauseActivity()
Activity.performPause()
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused(token)
ActivityManagerService.activityPaused()
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStack.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked()
ActivityStack.startSpecificActivityLocked
final class ActivityStack { ... private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { ... if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); } ... return true; } final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) { if (mPausingActivity != null) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity); completePauseLocked(false); } ActivityRecord prev = mResumedActivity; if (prev == null) { if (!resuming) { Slog.wtf(TAG, "Trying to pause when nothing is resumed"); mStackSupervisor.resumeTopActivitiesLocked(); } return false; } ... if (prev.app != null && prev.app.thread != null) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); try { EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, prev.userId, System.identityHashCode(prev), prev.shortComponentName); mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } } else { mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } ... } ... }
这里执行了pre.app.thread.schedulePauseActivity方法。这里prev是一个ActivityRecord
ActivityRecord.java
final class ActivityRecord { ProcessRecord app; // if non-null, hosting application ... }
这里APP是一个ProcessRecord
final class ProcessRecord { IApplicationThread thread; // the actual proc... may be null only if ... }
通过分析不难发现这里的thread是一个IApplicationThread
IApplicationThread.java 主要是一个接口
public interface IApplicationThread extends IInterface { void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException; void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException; void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException; void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException; void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs) throws RemoteException; void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException; void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config) throws RemoteException; void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) throws RemoteException; .... }
public final class ActivityThread { final ApplicationThread mAppThread = new ApplicationThread(); final H mH = new H(); private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1) { sendMessage(what, obj, arg1, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2) { sendMessage(what, obj, arg1, arg2, false); } private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); } private class H extends Handler { ... public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case PAUSE_ACTIVITY_FINISHING: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&1) != 0); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case STOP_ACTIVITY_SHOW: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); handleStopActivity((IBinder)msg.obj, true, msg.arg2); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case STOP_ACTIVITY_HIDE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); handleStopActivity((IBinder)msg.obj, false, msg.arg2); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... } } ... }
而在ActivityThread中也定义了一个ApplicationThread的类,其继承了IApplicationThread,并且都是Binder对象,
不难看出这里的IApplicationThread是一个Binder的client端,
而ActivityThread中的ApplicationThread是一个Binder对象的server端,
所以通过这里的thread.schedulePauseActivity实际上调用的就是ApplicationThread的schedulePauseActivity方法
这里的ApplicationThread可以和ActivityManagerNative对于一下:
通过ActivityManagerNative –> ActivityManagerService实现了应用进程与SystemServer进程的通讯
通过AppicationThread <– IApplicationThread实现了SystemServer进程与应用进程的通讯
ActivityThread.java#ApplicationThread 是ActivityThread的内部类
private class ApplicationThread extends ApplicationThreadNative { ... public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { sendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? 1 : 0) | (dontReport ? 2 : 0), configChanges); } public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) { sendMessage( showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, token, 0, configChanges); } public final void scheduleResumeActivity(IBinder token, int processState, boolean isForward, Bundle resumeArgs) { updateProcessState(processState, false); sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0); } public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); r.token = token; ... sendMessage(H.LAUNCH_ACTIVITY, r); } ... }
schedulePauseActivity是在内部类中调用ActivityThread的sendMessage()
最终调用了mH的sendMessage方法,mH是在ActivityThread中定义的一个Handler对象(主要处理SystemServer进程的消息)
Handler在handleMessage()可以发现其调用了handlePauseActivity方法
ActivityThread.java#handlePauseActivity
private void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { ActivityClientRecord r = mActivities.get(token); if (r != null) { //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); if (userLeaving) { performUserLeavingActivity(r); } r.activity.mConfigChangeFlags |= configChanges; performPauseActivity(token, finished, r.isPreHoneycomb()); // Make sure any pending writes are now committed. if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } // Tell the activity manager we have paused. if (!dontReport) { try { ActivityManagerNative.getDefault().activityPaused(token); } catch (RemoteException ex) { } } mSomeActivitiesChanged = true; } }
在方法体内部通过调用performPauseActivity方法来实现对栈顶Activity的onPause生命周期方法的回调,可以具体看一下他的实现:
ActivityThread.java#performPauseActivity
final Bundle performPauseActivity(IBinder token, boolean finished, boolean saveState) { ActivityClientRecord r = mActivities.get(token); return r != null ? performPauseActivity(r, finished, saveState) : null; } final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState) { ... mInstrumentation.callActivityOnPause(r.activity); ... return !r.activity.mFinished && saveState ? r.state : null; }
回到了mInstrumentation的callActivityOnPuase方法:
Instrumentation.java#callActivityOnPause
public void callActivityOnPause(Activity activity) { activity.performPause(); }
final void performPause() { mDoReportFullyDrawn = false; mFragments.dispatchPause(); mCalled = false; onPause(); mResumed = false; if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; }
回调到了Activity的onPause方法,也就是说我们在启动一个Activity的时候最先被执行的是栈顶的Activity的onPause方法。
然后回到我们的handlePauseActivity方法,在该方法的最后面执行了ActivityManagerNative.getDefault().activityPaused(token);方法,这是应用进程告诉服务进程,栈顶Activity已经执行完成onPause方法了,通过前面我们的分析,我们知道这句话最终会被ActivityManagerService的activityPaused方法执行。
ActivityManagerService.java#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方法
ActivityStack.java#activityPausedLocked
final void activityPausedLocked(IBinder token, boolean timeout) { ... if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); completePauseLocked(true); ... } private void completePauseLocked(boolean resumeNext) { ... if (resumeNext) { final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDown()) { mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null); } else { mStackSupervisor.checkReadyForSleepLocked(); ActivityRecord top = topStack.topRunningActivityLocked(null); 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.resumeTopActivitiesLocked(topStack, null, null); } }
经过了一系列的逻辑之后,又调用了resumeTopActivitiesLocked方法,又回到了第二步中解析的方法中了,这样经过
resumeTopActivitiesLocked –>
ActivityStack.resumeTopActivityLocked() –>
resumeTopActivityInnerLocked –>
startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { // Don't add this if it is a platform component that is marked // to run in multiple processes, because this is actually // part of the framework so doesn't make sense to track as a // separate apk in the process. app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
可以发现在这个方法中,首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。
这样关于启动Activity时的第三步骤就已经执行完成了,这里主要是实现了对栈顶Activity执行onPause
方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity