本篇所涉及知識點:
- Android 從開機到第一個Activity onCreate的過程粗略分析
- Activity_A進入Activity_B生命週期的回調詳細過程(Activity_A的onPause-->Activity_B的onCreate,onStart,onResume-->Activity_A的onStop,期間會看到Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法的回調源碼)
須要瞭解的幾點概念和知識點:
- Instrumentation是執行application instrumentation代碼的基類,這個類在任何application code以前實例化,讓你能夠監聽全部的system與application之間的交互,一個應用程序中只有一個Instrumentation對象,每一個Activity內部都有一個該對象的引用Instrumentation能夠幫助管理Activity生命週期的回調,經過追蹤源碼會發現,Instrumentation的callActivityOnPause最終會去調用activity的performPause(),
- ActivityResult是Instrumentation的一個內部類,是Activity返回的一個結果,包含了resultCode和resultData
- ActivityThread類: 該類爲應用程序的主線程類,全部的APK程序都有且僅有一個ActivityThread類 ,程序的入口爲該類中的static main()函數
- IApplicationThread是一個接口
- ApplicationThreadNative是一個抽象類,實現了IApplicationThread接口,並繼承Binder,具備Binder通訊能力,public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
- ApplicationThread 繼承了ApplicationThreadNative,是ActivityThread 的一個內部類
- H也是ActivityThread的一個內部類,繼承Handler,處理Activty,Service等生命週期的回調消息
- ActivityStackSupervisor 類是用來輔助管理ActivityStack的,裏面有mHomeStack,mFocusedStack 和 mLastFocusedStack,它們的類型都是ActivityStack ,ActivityStackSupervisor 中主要是對它們的調度算法的一些操做
- 盜用一張圖,出自http://blog.csdn.net/caowenbin/article/details/6036726
![](http://static.javashuo.com/static/loading.gif)
- 關於上圖的說明:
- Binder是一種架構,這種架構提供了服務端接口、Binder驅動、客戶端接口三個模塊,用於完成進程間通訊(IPC)
- IActivityManager是一個接口
- ActivityManagerNative 繼承了 Binder 和實現了IActivityManager接口 ,具備Binder通訊能力
- ActivityManagerService 繼承了 ActivityManagerNative,是最核心的服務之一,負責管理Activity
- ActivityManagerProxy是ActivityManagerNative的一個內部類,也實現了IActivityManager接口
- 在開發過程當中,程序員能接觸到的也就是ActivityManager,系統不但願用戶直接訪問ActivityManagerService,而是通過ActivityManager類去訪問,好比說經過activityManager.getRecentTasks獲得最近使用的程序,在前面的博客《一個叫GUN的有趣的APP》使用過這個方法
- 可是ActivityManagerService和ActivityManager運行在不一樣的進程中,它們究竟是如何通訊的?這就是Proxy代理模式:爲其餘對象提供一種代理以控制這個對象的訪問。
- activityManager.getRecentTasks動做真正的執行者是ActivityManagerService.getRecentTasks,關於這點,下面會有具體的代碼分析
說明:如下源碼基於android-22(5.1)分析。java
Android 從開機到第一個Activity onCreate的過程大體分析
- 開機後,Linux啓動,而後Linux再啓動第一個進程init
- 在init中,又會啓動Zygote
- Zygote則會啓動SystemServer
- SystemServer又會開啓Application FrameWork中的AMS(Activity Manager Service),PMS(package Manager Service),WMS(WindowManager Service)等,這致使的結果就是Android 開機比較慢
- 在被SystemServer啓動的AMS中,有一個叫startHomeActivityLocked的函數,它建立一個CATEGORY_HOME類型的Intent,而PackageManagerService會查詢Category類型爲HOME的Activity,由於只有系統自帶的Launcher應用程序註冊了HOME類型的Activity(若是有多個Launcher的話,系統會彈出一個選擇框讓用戶選擇進入哪個Launcher)
- 而後又會執行mMainStack.startActivityLocked啓動Launcher的Activity
- 接下來就是調用它的onCreate
這樣總算從開機一步一步走到了Activity的第一個執行的生命週期。android
說明1:android的launcher應用程序,即桌面應用程序(注意,Android開機啓動後的桌面也是一個APP,只不過這個APP有點特殊,開發難度有點大而已,Android原生系統的launcher的包名叫"com.android.launcher",小米launcher的包名叫"com.miui.home",這是之前寫《一個叫GUN的有趣的APP》時發現的),這個launcher負責把安裝在手機上的APP以快捷圖標的形式展現出來。
說明2:由於以上涉及到Linux方面知識,由於徹底不懂,只弄懂了大體流程,因此不敢保證上面的進程步驟嚴謹正確(之後待研究)。程序員
Activity_A進入Activity_B生命週期的回調詳細過程
執行代碼:算法
[java] view plain copywindows
- Intent intent = new Intent(Activity_A.this, Activity_B.class);
- startActivity(intent);
它們的生命週期執行過程:架構
![](http://static.javashuo.com/static/loading.gif)
對於這個生命週期的執行過程,應該都很熟了,可是有一點疑問:爲何執行了Activity_A的onPause以後就直接去執行Activity_B的onCreate,onStart,onResume,最後才掉過頭回去執行Activity_A的onStop?app
進入源碼分析(由於所涉及到的代碼邏輯太多太多,因此如下分析主要基於Activity生命週期回調執行的主線)。ide
Activity.class函數
[java] view plain copyoop
- public void startActivity(Intent intent) {
- this.startActivity(intent, null);
- }
-
- public void startActivity(Intent intent, @Nullable Bundle options) {
- if (options != null) {
- startActivityForResult(intent, -1, options);
- } else {
- // Note we want to go through this call for compatibility with
- // applications that may have overridden the method.
- startActivityForResult(intent, -1);
- }
- }
-
- public void startActivityForResult(Intent intent, int requestCode,
- @Nullable Bundle options) {
- if (mParent == null) {
- //這是關鍵的一句,啓動新的Activity
- Instrumentation.ActivityResult ar = mInstrumentation
- .execStartActivity(this,
- mMainThread.getApplicationThread(), mToken, this,
- intent, requestCode, options);
- if (ar != null) {
- mMainThread.sendActivityResult(mToken, mEmbeddedID,
- requestCode, ar.getResultCode(), ar.getResultData());
- }
- if (requestCode >= 0) {
- // If this start is requesting a result, we can avoid making
- // the activity visible until the result is received. Setting
- // this code during onCreate(Bundle savedInstanceState) or
- // onResume() will keep the
- // activity hidden during this time, to avoid flickering.
- // This can only be done when a result is requested because
- // that guarantees we will get information back when the
- // activity is finished, no matter what happens to it.
- mStartedActivity = true;
- }
-
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
- // TODO Consider clearing/flushing other event sources and events
- // for child windows.
- } else {
- if (options != null) {
- mParent.startActivityFromChild(this, intent, requestCode,
- options);
- } else {
- // Note we want to go through this method for compatibility with
- // existing applications that may have overridden it.
- mParent.startActivityFromChild(this, intent, requestCode);
- }
- }
- if (options != null && !isTopOfTask()) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
- }
很是很是關鍵的mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
這個mInstrumentation就是上面提到的Instrumentation,引用《Android內核剖析》對它的描述:一個應用程序中只有一個Instrumentation對象,每一個Activity內部都有一個該對象的引用。Instrumentation能夠理解爲應用進程的管家, ActivityThread要建立或者暫停某 個 Activity時,是 通 過 這 個「 管家」 進行的,設置這個管家的好處是能夠統計全部的「 開銷」,開銷的信息保存在「 管家」 那裏。其實正如其名稱所示,Instrumentation就是爲了 「測量」、 「統計」,由於管家掌握了全部的「 開銷」,天然也就具備了統計的功能。固然,Instrumentation類 和 ActivityThread的分工是有本質區別的,後者就像是這個家裏的主人,負責建立這個「家庭」,並負責和外界打交道,好比 接 收AMS的通知等。
Instrumentation能夠幫助管理Activity生命週期的回調。
Instrumentation.class
[java] view plain copy
- public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
- IApplicationThread whoThread = (IApplicationThread) contextThread;
- if (mActivityMonitors != null) {
- synchronized (mSync) {
- final int N = mActivityMonitors.size();
- for (int i=0; i<N; i++) {
- final ActivityMonitor am = mActivityMonitors.get(i);
- if (am.match(who, null, intent)) {
- am.mHits++;
- if (am.isBlocking()) {
- return requestCode >= 0 ? am.getResult() : null;
- }
- break;
- }
- }
- }
- }
- try {
- intent.migrateExtraStreamToClipData();
- intent.prepareToLeaveProcess();
- //關鍵,Proxy代理模式,真正的動做執行者是ActivityManagerService.startActivity
- int result = ActivityManagerNative.getDefault()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
- checkStartActivityResult(result, intent);
- } catch (RemoteException e) {
- }
- return null;
- }
大體介紹一下Proxy代理模式,看看這個ActivityManagerNative.getDefault()究竟是什麼?
ActivityManagerNative.class
[java] view plain copy
- /**
- * Retrieve the system's default/global activity manager.
- */
- static public IActivityManager getDefault() {
- return gDefault.get();
- }
-
- private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
- protected IActivityManager create() {
- IBinder b = ServiceManager.getService("activity");
- if (false) {
- Log.v("ActivityManager", "default service binder = " + b);
- }
- IActivityManager am = asInterface(b);
- if (false) {
- Log.v("ActivityManager", "default service = " + am);
- }
- return am;
- }
- };
說明:
IBinder是用來通訊的,getDefault()返回的是一個IActivityManager類型的ActivityManagerProxy對象,代理的是ActivityManagerNative類的子類ActivityManagerService,代理成功以後,即可以經過這個代理對象使用IBinder和系統不但願用戶直接訪問的ActivityManagerService進行通訊,並執行ActivityManagerService中具體定義的動做了。
再次以activityManager.getRecentTasks爲例再進行說明:
ActivityManager.class
[java] view plain copy
- @Deprecated
- public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
- throws SecurityException {
- try {
- return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
- flags, UserHandle.myUserId());
- } catch (RemoteException e) {
- // System dead, we will be dead too soon!
- return null;
- }
- }
這裏也是經過ActivityManagerNative.getDefault()代理,ActivityManager並無執行其具體的動做,真正動做的執行在經過ActivityManagerNative.getDefault()代理的ActivityManagerService裏面。
代理模式大體理解了,繼續分析:
- ActivityManagerNative.getDefault()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
裏面的參數whoThread就是前面的MainThread.getApplicationThread,mMainThread的類型是ActivityThread,它表明的是應用程序的主線程,這裏經過 mMainThread.getApplicationThread得到它裏面的ApplicationThread成員變量,具備Binder通訊能力。
按照上面的分析,如今能夠知道ActivityManagerNative.getDefault().startActivity真正的動做執行是在ActivityManagerService.startActivity裏面,跟蹤源碼:
ActivityManagerService.class
[java] view plain copy
- @Override
- public final int startActivity(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options) {
- return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
- resultWho, requestCode, startFlags, profilerInfo, options,
- UserHandle.getCallingUserId());
- }
-
- @Override
- public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
- enforceNotIsolatedCaller("startActivity");
- userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
- false, ALLOW_FULL_ONLY, "startActivity", null);
- // TODO: Switch to user app stacks here.
- return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
- resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- profilerInfo, null, null, options, userId, null, null);
- }
ActivityStackSupervisor.class
[java] view plain copy
- final int startActivityMayWait(IApplicationThread caller, int callingUid,
- String callingPackage, Intent intent, String resolvedType,
- IVoiceInteractionSession voiceSession,
- IVoiceInteractor voiceInteractor, IBinder resultTo,
- String resultWho, int requestCode, int startFlags,
- ProfilerInfo profilerInfo, WaitResult outResult,
- Configuration config, Bundle options, int userId,
- IActivityContainer iContainer, TaskRecord inTask) {
- // Refuse possible leaked file descriptors
- if (intent != null && intent.hasFileDescriptors()) {
- throw new IllegalArgumentException(
- "File descriptors passed in Intent");
- }
- // ...
-
- if (aInfo != null
- && (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
- // ...
- }
-
- int res = startActivityLocked(caller, intent, resolvedType, aInfo,
- voiceSession, voiceInteractor, resultTo, resultWho,
- requestCode, callingPid, callingUid, callingPackage,
- realCallingPid, realCallingUid, startFlags, options,
- componentSpecified, null, container, inTask);
-
- // ...
-
- return res;
- }
ActivityStackSupervisor 類是用來輔助管理ActivityStack的,在ActivityStackSupervisor中能夠看到
ActivityStackSupervisor.class
[java] view plain copy
- /** The stack containing the launcher app. Assumed to always be attached to
- * Display.DEFAULT_DISPLAY. */
- private ActivityStack mHomeStack;
-
- /** The stack currently receiving input or launching the next activity. */
- private ActivityStack mFocusedStack;
-
- /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
- * been resumed. If stacks are changing position this will hold the old stack until the new
- * stack becomes resumed after which it will be set to mFocusedStack. */
- private ActivityStack mLastFocusedStack;
裏面有mHomeStack,mFocusedStack 和 mLastFocusedStack,它們的類型都是ActivityStack 。從Google註釋中能夠理解,mHomeStack保存launcher app的Activity,mFocusedStack保存當前接受輸入事件和正啓動的下一個Activity。ActivityStackSupervisor 中主要是對它們的調度算法的一些操做。
上面startActivityMayWait返回的結果是經過startActivityLocked獲得的res,繼續追蹤startActivityLocked:
ActivityStackSupervisor.class
[java] view plain copy
- final int startActivityLocked(IApplicationThread caller,
- Intent intent, String resolvedType, ActivityInfo aInfo,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode,
- int callingPid, int callingUid, String callingPackage,
- int realCallingPid, int realCallingUid, int startFlags, Bundle options,
- boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
- TaskRecord inTask) {
- int err = ActivityManager.START_SUCCESS;
- ProcessRecord callerApp = null;
- if (caller != null) {
- //...
- }
- //...
- if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
- //...
- }
-
- if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
- // We couldn't find a class that can handle the given Intent.
- // That's the end of that!
- err = ActivityManager.START_INTENT_NOT_RESOLVED;
- }
-
- if (err == ActivityManager.START_SUCCESS && aInfo == null) {
- // We couldn't find the specific class specified in the Intent.
- // Also the end of the line.
- err = ActivityManager.START_CLASS_NOT_FOUND;
- }
- //...
- err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, true, options, inTask);
- //...
- return err;
- }
主要是檢查目標APP或者Activity的一些信息,包括是否存在,是否擁有權限等,最後又會調用startActivityUncheckedLocked,此時目標Activity通過了經過了檢查。
startActivityUncheckedLocked中又調用了targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options),這裏跟上面的ActivityStackSupervisor.startActivityLocked方法名相同。
ActivityStack.class
[java] view plain copy
- final void startActivityLocked(ActivityRecord r, boolean newTask,
- boolean doResume, boolean keepCurTransition, Bundle options) {
- TaskRecord rTask = r.task;
- final int taskId = rTask.taskId;
- // mLaunchTaskBehind tasks get placed at the back of the task stack.
- if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
- // Last activity in task had been removed or ActivityManagerService is reusing task.
- // Insert or replace.
- // Might not even be in.
- //若是是新任務,插入棧頂
- insertTaskAtTop(rTask);
- mWindowManager.moveTaskToTop(taskId);
- }
- TaskRecord task = null;
- if (!newTask) {
- // If starting in an existing task, find where that is...
- //若是不是是新任務
- boolean startIt = true;
- //遍歷mHistory
- for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- task = mTaskHistory.get(taskNdx);
- if (task.getTopActivity() == null) {
- // All activities in task are finishing.
- continue;
- }
- if (task == r.task) {
- // Here it is! Now, if this is not yet visible to the
- // user, then just add it without starting; it will
- // get started when the user navigates back to it.
- if (!startIt) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
- + task, new RuntimeException("here").fillInStackTrace());
- task.addActivityToTop(r);
- r.putInHistory();
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
- r.userId, r.info.configChanges, task.voiceSession != null,
- r.mLaunchTaskBehind);
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
- ActivityOptions.abort(options);
- return;
- }
- break;
- } else if (task.numFullscreen > 0) {
- startIt = false;
- }
- }
- }
-
- // Place a new activity at top of stack, so it is next to interact
- // with the user.
-
- // If we are not placing the new activity frontmost, we do not want
- // to deliver the onUserLeaving callback to the actual frontmost
- // activity
- if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
- //...
- }
-
- //...
- if (!isHomeStack() || numActivities() > 0) {
- //...
- } else {
- //...
- }
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
-
- if (doResume) {
- mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
- }
- }
在ActivityStackSupervisor.startActivityUncheckedLocked和ActivityStack.startActivityLocked主要是找到或建立合適的Task,根據FLAG_ACTIVITY_XX(啓動模式)進行不一樣的Task操做,這裏調度task的算法很複雜。
上面執行完成以後,調用mStackSupervisor.resumeTopActivitiesLocked(this, r, options);ActivityStack
ActivityStackSupervisor.class
[java] view plain copy
- boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
- Bundle targetOptions) {
- if (targetStack == null) {
- targetStack = getFocusedStack();
- }
- // Do targetStack first.
- boolean result = false;
- if (isFrontStack(targetStack)) {
- result = targetStack.resumeTopActivityLocked(target, targetOptions);
- }
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack == targetStack) {
- // Already started above.
- continue;
- }
- if (isFrontStack(stack)) {
- stack.resumeTopActivityLocked(null);
- }
- }
- }
- return result;
- }
ActivityStack.class
[java] view plain copy
- final boolean resumeTopActivityLocked(ActivityRecord prev) {
- return resumeTopActivityLocked(prev, null);
- }
-
- final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
- if (mStackSupervisor.inResumeTopActivity) {
- // Don't even start recursing.
- return false;
- }
-
- boolean result = false;
- try {
- // Protect against recursion.
- mStackSupervisor.inResumeTopActivity = true;
- if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
- mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
- mService.updateSleepIfNeededLocked();
- }
- result = resumeTopActivityInnerLocked(prev, options);
- } finally {
- mStackSupervisor.inResumeTopActivity = false;
- }
- return result;
- }
ActivityStack.class
resumeTopActivityInnerLocked方法裏面代碼太多
[java] view plain copy
- final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
- //...
-
- // Find the first activity that is not finishing.
- //找到第一個沒有finish的activity,這個Activity就是Activity_A
- final ActivityRecord next = topRunningActivityLocked(null);
-
- // Remember how we'll process this pause/resume situation, and ensure
- // that the state is reset however we wind up proceeding.
- final boolean userLeaving = mStackSupervisor.mUserLeaving;
- mStackSupervisor.mUserLeaving = false;
-
- final TaskRecord prevTask = prev != null ? prev.task : null;
- //若是是開機啓動,則next==null,因此就是啓動Launcher了
- if (next == null) {
- // There are no more activities! Let's just start up the
- // Launcher...
- ActivityOptions.abort(options);
- if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
- if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
- // Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
- }
-
-
- //...
- // We need to start pausing the current activity so the top one
- // can be resumed...
- //去 pause當前處於resumed狀態的Activity,也就是Activity_A
- boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
- if (mResumedActivity != null) {
- if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
- pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
- }
- //...
- if (prev != null && prev != next) {}
-
- //...
-
- return true;
- }
這裏先分析Launcher的啓動函數 resumeHomeStackTask
ActivityStackSupervisor.class
[java] view plain copy
- boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
- if (!mService.mBooting && !mService.mBooted) {
- // Not ready yet!
- return false;
- }
-
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return false;
- }
- moveHomeStackTaskToTop(homeStackTaskType, reason);
- if (prev != null) {
- prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- }
-
- ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
- // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
- if (r != null && r.isHomeActivity()) {
- mService.setFocusedActivityLocked(r, reason);
- return resumeTopActivitiesLocked(mHomeStack, prev, null);
- }
- //啓動Launcher
- return mService.startHomeActivityLocked(mCurrentUser, reason);
- }
mService.startHomeActivityLocked(mCurrentUser, reason)啓動Launcher
ActivityManagerService.class
[java] view plain copy
- boolean startHomeActivityLocked(int userId, String reason) {
- if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
- && mTopAction == null) {
- // We are running in factory test mode, but unable to find
- // the factory test app, so just sit around displaying the
- // error message and don't try to start anything.
- return false;
- }
- Intent intent = getHomeIntent();
- ActivityInfo aInfo =
- resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
- if (aInfo != null) {
- intent.setComponent(new ComponentName(
- aInfo.applicationInfo.packageName, aInfo.name));
- // Don't do this if the home app is currently being
- // instrumented.
- aInfo = new ActivityInfo(aInfo);
- aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
- ProcessRecord app = getProcessRecordLocked(aInfo.processName,
- aInfo.applicationInfo.uid, true);
- if (app == null || app.instrumentationClass == null) {
- intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
- mStackSupervisor.startHomeActivity(intent, aInfo, reason);
- }
- }
-
- return true;
- }
ActivityStackSupervisor.class
[java] view plain copy
- void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
- moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
- startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
- 0, 0, 0, null, false, null, null, null);
- }
裏面也是調用了startActivityLocked,若是想定義本身的Launcher的話,貌似就能夠在這裏修改代碼了。
再去追蹤startPausingLocked
ActivityStack.class
[java] view plain copy
- 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);
- }
- //prev包含了Activity_A,因此prev.app != null && prev.app.thread != null
- 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, "Enqueueing pending pause: " + prev);
- try {
- EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
- prev.userId, System.identityHashCode(prev),
- prev.shortComponentName);
- mService.updateUsageStats(prev, false);
- //這句是關鍵,經過Binder調用ActivityThread中的方法,AmS 會經過 IPC 調用到 ActivityThread 的schedulePauseActivity
- 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;
- }
-
- //...
- return false;
- }
疑問:爲何prev.app.thread.schedulePauseActivity能調用到ApplicationThread中的schedulePauseActivity方法?
----Binder機制,具體怎麼實現的我也沒弄明白。
ActivityThread.class
ApplicationThread是ActivityThread的一個內部類,有木有感受裏面的方法是那麼熟悉?
[java] view plain copy
- 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 scheduleWindowVisibility(IBinder token, boolean showWindow) {
- sendMessage(
- showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
- token);
- }
-
- public final void scheduleSleeping(IBinder token, boolean sleeping) {
- sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
- }
-
- 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 scheduleSendResult(IBinder token, List<ResultInfo> results) {
- ResultData res = new ResultData();
- res.token = token;
- res.results = results;
- sendMessage(H.SEND_RESULT, res);
- }
-
- // we use token to identify this activity without having to send the
- // activity itself back to the activity manager. (matters more with ipc)
- public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
- PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
- ProfilerInfo profilerInfo) {
-
- updateProcessState(procState, false);
-
- ActivityClientRecord r = new ActivityClientRecord();
-
- r.token = token;
- r.ident = ident;
- r.intent = intent;
- r.referrer = referrer;
- r.voiceInteractor = voiceInteractor;
- r.activityInfo = info;
- r.compatInfo = compatInfo;
- r.state = state;
- r.persistentState = persistentState;
-
- r.pendingResults = pendingResults;
- r.pendingIntents = pendingNewIntents;
-
- r.startsNotResumed = notResumed;
- r.isForward = isForward;
-
- r.profilerInfo = profilerInfo;
-
- updatePendingConfiguration(curConfig);
-
- sendMessage(H.LAUNCH_ACTIVITY, r);
- }
-
- public final void scheduleRelaunchActivity(IBinder token,
- List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
- int configChanges, boolean notResumed, Configuration config) {
- requestRelaunchActivity(token, pendingResults, pendingNewIntents,
- configChanges, notResumed, config, true);
- }
-
- public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
- NewIntentData data = new NewIntentData();
- data.intents = intents;
- data.token = token;
-
- sendMessage(H.NEW_INTENT, data);
- }
-
- public final void scheduleDestroyActivity(IBinder token, boolean finishing,
- int configChanges) {
- sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
- configChanges);
- }
-
- public final void scheduleReceiver(Intent intent, ActivityInfo info,
- CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
- boolean sync, int sendingUser, int processState) {
- updateProcessState(processState, false);
- ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
- sync, false, mAppThread.asBinder(), sendingUser);
- r.info = info;
- r.compatInfo = compatInfo;
- sendMessage(H.RECEIVER, r);
- }
-
- //...
- public final void scheduleCreateService(IBinder token,
- ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
- updateProcessState(processState, false);
- CreateServiceData s = new CreateServiceData();
- s.token = token;
- s.info = info;
- s.compatInfo = compatInfo;
-
- sendMessage(H.CREATE_SERVICE, s);
- }
-
- public final void scheduleBindService(IBinder token, Intent intent,
- boolean rebind, int processState) {
- updateProcessState(processState, false);
- BindServiceData s = new BindServiceData();
- s.token = token;
- s.intent = intent;
- s.rebind = rebind;
-
- if (DEBUG_SERVICE)
- Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
- + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
- sendMessage(H.BIND_SERVICE, s);
- }
-
- //...
- }
schedulePauseActivity裏面有個H.PAUSE_ACTIVITY_FINISHING。
前面說過,H也是ActivityThread的一個內部類,繼承Handler,用來處理Activty,Service等生命週期的回調消息。關於Handler Loopr的通訊原理,能夠參考一下之前寫過一篇博文《從Android源碼角度對Handler,MessageQueue,Looper之間消息傳遞工做原理的理解》。
ActivityThread.class
[java] view plain copy
- 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.class
[java] view plain copy
- 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;
- }
- }
ActivityThread.class
[java] view plain copy
- 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) {
- if (r.paused) {
- //...
- }
- if (finished) {
- //...
- }
- try {
- // Next have the activity save its current state and managed dialogs...
- //通知Activity_A調用onSaveInstanceState保存狀態
- if (!r.activity.mFinished && saveState) {
- callCallActivityOnSaveInstanceState(r);
- }
- // Now we are idle.
- //通知Activity_A調用OnPause方法
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnPause(r.activity);
- EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
- r.activity.getComponentName().getClassName());
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString() +
- " did not call through to super.onPause()");
- }
-
- } catch (SuperNotCalledException e) {
- throw e;
-
- } catch (Exception e) {
- //...
- }
- r.paused = true;
- return !r.activity.mFinished && saveState ? r.state : null;
- }
在這裏終於明白了,在啓動目標Activity前,若是當前正在運行任何Activity,那麼必須首先暫停。
追蹤mInstrumentation.callActivityOnPause(r.activity)
Instrumentation.class
[java] view plain copy
- public void callActivityOnPause(Activity activity) {
- activity.performPause();
- }
Activity.class
[java] view plain copy
- 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_A已經執行onPause方法,Activity_B未執行其生命週期的任何方法。
在下一篇中將繼續去追蹤Activity_B生命週期回調源碼。