Activity生命週期的回調,你應該知道得更多!--Android源碼剖析(上)

本篇所涉及知識點:

 

  • Android 從開機到第一個Activity onCreate的過程粗略分析
  • Activity_A進入Activity_B生命週期的回調詳細過程(Activity_A的onPause-->Activity_B的onCreate,onStart,onResume-->Activity_A的onStop,期間會看到Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法的回調源碼)

須要瞭解的幾點概念和知識點:

  1. Instrumentation是執行application instrumentation代碼的基類,這個類在任何application code以前實例化,讓你能夠監聽全部的system與application之間的交互,一個應用程序中只有一個Instrumentation對象,每一個Activity內部都有一個該對象的引用Instrumentation能夠幫助管理Activity生命週期的回調,經過追蹤源碼會發現,Instrumentation的callActivityOnPause最終會去調用activity的performPause(),
  2. ActivityResult是Instrumentation的一個內部類,是Activity返回的一個結果,包含了resultCode和resultData
  3. ActivityThread類: 該類爲應用程序的主線程類,全部的APK程序都有且僅有一個ActivityThread類 ,程序的入口爲該類中的static main()函數
  4.  IApplicationThread是一個接口
  5.  ApplicationThreadNative是一個抽象類,實現了IApplicationThread接口,並繼承Binder,具備Binder通訊能力,public abstract class ApplicationThreadNative extends Binder implements IApplicationThread 
  6. ApplicationThread 繼承了ApplicationThreadNative,是ActivityThread 的一個內部類       
  7. H也是ActivityThread的一個內部類,繼承Handler,處理Activty,Service等生命週期的回調消息
  8. ActivityStackSupervisor 類是用來輔助管理ActivityStack的,裏面有mHomeStack,mFocusedStack 和 mLastFocusedStack,它們的類型都是ActivityStack ,ActivityStackSupervisor 中主要是對它們的調度算法的一些操做
  9. 盜用一張圖,出自http://blog.csdn.net/caowenbin/article/details/6036726
  10. 關於上圖的說明:
    1. Binder是一種架構,這種架構提供了服務端接口、Binder驅動、客戶端接口三個模塊,用於完成進程間通訊(IPC)
    2. IActivityManager是一個接口
    3. ActivityManagerNative 繼承了 Binder 和實現了IActivityManager接口 ,具備Binder通訊能力
    4. ActivityManagerService 繼承了 ActivityManagerNative,是最核心的服務之一,負責管理Activity
    5. ActivityManagerProxy是ActivityManagerNative的一個內部類,也實現了IActivityManager接口
    6. 在開發過程當中,程序員能接觸到的也就是ActivityManager,系統不但願用戶直接訪問ActivityManagerService,而是通過ActivityManager類去訪問,好比說經過activityManager.getRecentTasks獲得最近使用的程序,在前面的博客《一個叫GUN的有趣的APP》使用過這個方法
    7. 可是ActivityManagerService和ActivityManager運行在不一樣的進程中,它們究竟是如何通訊的?這就是Proxy代理模式:爲其餘對象提供一種代理以控制這個對象的訪問。
    8. activityManager.getRecentTasks動做真正的執行者是ActivityManagerService.getRecentTasks,關於這點,下面會有具體的代碼分析

       說明:如下源碼基於android-22(5.1)分析。java

Android 從開機到第一個Activity onCreate的過程大體分析

  1. 開機後,Linux啓動,而後Linux再啓動第一個進程init 
  2. 在init中,又會啓動Zygote
  3. Zygote則會啓動SystemServer
  4. SystemServer又會開啓Application FrameWork中的AMS(Activity Manager Service),PMS(package Manager Service),WMS(WindowManager Service)等,這致使的結果就是Android 開機比較慢
  5. 在被SystemServer啓動的AMS中,有一個叫startHomeActivityLocked的函數,它建立一個CATEGORY_HOME類型的Intent,而PackageManagerService會查詢Category類型爲HOME的Activity,由於只有系統自帶的Launcher應用程序註冊了HOME類型的Activity(若是有多個Launcher的話,系統會彈出一個選擇框讓用戶選擇進入哪個Launcher)
  6. 而後又會執行mMainStack.startActivityLocked啓動Launcher的Activity
  7. 接下來就是調用它的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

  1. Intent intent = new Intent(Activity_A.this, Activity_B.class);    
  2. startActivity(intent);  

        它們的生命週期執行過程:架構

        對於這個生命週期的執行過程,應該都很熟了,可是有一點疑問:爲何執行了Activity_A的onPause以後就直接去執行Activity_B的onCreate,onStart,onResume,最後才掉過頭回去執行Activity_A的onStop?app

        進入源碼分析(由於所涉及到的代碼邏輯太多太多,因此如下分析主要基於Activity生命週期回調執行的主線)。ide

        Activity.class函數

[java] view plain copyoop

  1. public void startActivity(Intent intent) {  
  2.     this.startActivity(intent, null);  
  3. }  
  4.   
  5. public void startActivity(Intent intent, @Nullable Bundle options) {  
  6.     if (options != null) {  
  7.         startActivityForResult(intent, -1, options);  
  8.     } else {  
  9.         // Note we want to go through this call for compatibility with  
  10.         // applications that may have overridden the method.  
  11.         startActivityForResult(intent, -1);  
  12.     }  
  13. }  
  14.   
  15. public void startActivityForResult(Intent intent, int requestCode,  
  16.         @Nullable Bundle options) {  
  17.     if (mParent == null) {  
  18.         //這是關鍵的一句,啓動新的Activity  
  19.         Instrumentation.ActivityResult ar = mInstrumentation  
  20.                 .execStartActivity(this,  
  21.                         mMainThread.getApplicationThread(), mToken, this,  
  22.                         intent, requestCode, options);  
  23.         if (ar != null) {  
  24.             mMainThread.sendActivityResult(mToken, mEmbeddedID,  
  25.                     requestCode, ar.getResultCode(), ar.getResultData());  
  26.         }  
  27.         if (requestCode >= 0) {  
  28.             // If this start is requesting a result, we can avoid making  
  29.             // the activity visible until the result is received. Setting  
  30.             // this code during onCreate(Bundle savedInstanceState) or  
  31.             // onResume() will keep the  
  32.             // activity hidden during this time, to avoid flickering.  
  33.             // This can only be done when a result is requested because  
  34.             // that guarantees we will get information back when the  
  35.             // activity is finished, no matter what happens to it.  
  36.             mStartedActivity = true;  
  37.         }  
  38.   
  39.         final View decor = mWindow != null ? mWindow.peekDecorView() : null;  
  40.         if (decor != null) {  
  41.             decor.cancelPendingInputEvents();  
  42.         }  
  43.         // TODO Consider clearing/flushing other event sources and events  
  44.         // for child windows.  
  45.     } else {  
  46.         if (options != null) {  
  47.             mParent.startActivityFromChild(this, intent, requestCode,  
  48.                     options);  
  49.         } else {  
  50.             // Note we want to go through this method for compatibility with  
  51.             // existing applications that may have overridden it.  
  52.             mParent.startActivityFromChild(this, intent, requestCode);  
  53.         }  
  54.     }  
  55.     if (options != null && !isTopOfTask()) {  
  56.         mActivityTransitionState.startExitOutTransition(this, options);  
  57.     }  
  58. }  

        很是很是關鍵的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

  1. public ActivityResult execStartActivity(  
  2.             Context who, IBinder contextThread, IBinder token, Activity target,  
  3.             Intent intent, int requestCode, Bundle options) {  
  4.         IApplicationThread whoThread = (IApplicationThread) contextThread;  
  5.         if (mActivityMonitors != null) {  
  6.             synchronized (mSync) {  
  7.                 final int N = mActivityMonitors.size();  
  8.                 for (int i=0; i<N; i++) {  
  9.                     final ActivityMonitor am = mActivityMonitors.get(i);  
  10.                     if (am.match(who, null, intent)) {  
  11.                         am.mHits++;  
  12.                         if (am.isBlocking()) {  
  13.                             return requestCode >= 0 ? am.getResult() : null;  
  14.                         }  
  15.                         break;  
  16.                     }  
  17.                 }  
  18.             }  
  19.         }  
  20.         try {  
  21.             intent.migrateExtraStreamToClipData();  
  22.             intent.prepareToLeaveProcess();  
  23.             //關鍵,Proxy代理模式,真正的動做執行者是ActivityManagerService.startActivity  
  24.             int result = ActivityManagerNative.getDefault()  
  25.                 .startActivity(whoThread, who.getBasePackageName(), intent,  
  26.                         intent.resolveTypeIfNeeded(who.getContentResolver()),  
  27.                         token, target != null ? target.mEmbeddedID : null,  
  28.                         requestCode, 0, null, options);  
  29.             checkStartActivityResult(result, intent);  
  30.         } catch (RemoteException e) {  
  31.         }  
  32.         return null;  
  33.     }  


        大體介紹一下Proxy代理模式,看看這個ActivityManagerNative.getDefault()究竟是什麼?

        ActivityManagerNative.class

[java] view plain copy

  1. /** 
  2.  * Retrieve the system's default/global activity manager. 
  3.  */  
  4. static public IActivityManager getDefault() {  
  5.     return gDefault.get();  
  6. }  
  7.   
  8. private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {  
  9.     protected IActivityManager create() {  
  10.         IBinder b = ServiceManager.getService("activity");  
  11.         if (false) {  
  12.             Log.v("ActivityManager", "default service binder = " + b);  
  13.         }  
  14.         IActivityManager am = asInterface(b);  
  15.         if (false) {  
  16.             Log.v("ActivityManager", "default service = " + am);  
  17.         }  
  18.         return am;  
  19.     }  
  20. };  

        說明:

        IBinder是用來通訊的,getDefault()返回的是一個IActivityManager類型的ActivityManagerProxy對象,代理的是ActivityManagerNative類的子類ActivityManagerService,代理成功以後,即可以經過這個代理對象使用IBinder和系統不但願用戶直接訪問的ActivityManagerService進行通訊,並執行ActivityManagerService中具體定義的動做了。

        再次以activityManager.getRecentTasks爲例再進行說明:

        ActivityManager.class

[java] view plain copy

  1. @Deprecated  
  2. public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)  
  3.         throws SecurityException {  
  4.     try {  
  5.         return ActivityManagerNative.getDefault().getRecentTasks(maxNum,  
  6.                 flags, UserHandle.myUserId());  
  7.     } catch (RemoteException e) {  
  8.         // System dead, we will be dead too soon!  
  9.         return null;  
  10.     }  
  11. }  

        這裏也是經過ActivityManagerNative.getDefault()代理,ActivityManager並無執行其具體的動做,真正動做的執行在經過ActivityManagerNative.getDefault()代理的ActivityManagerService裏面。

 

        代理模式大體理解了,繼續分析:

 

  1. ActivityManagerNative.getDefault()  
  2.                 .startActivity(whoThread, who.getBasePackageName(), intent,  
  3.                         intent.resolveTypeIfNeeded(who.getContentResolver()),  
  4.                         token, target != null ? target.mEmbeddedID : null,  
  5.                         requestCode, 0, null, options); 

 

        裏面的參數whoThread就是前面的MainThread.getApplicationThread,mMainThread的類型是ActivityThread,它表明的是應用程序的主線程,這裏經過 mMainThread.getApplicationThread得到它裏面的ApplicationThread成員變量,具備Binder通訊能力。

        按照上面的分析,如今能夠知道ActivityManagerNative.getDefault().startActivity真正的動做執行是在ActivityManagerService.startActivity裏面,跟蹤源碼:

        ActivityManagerService.class

[java] view plain copy

  1. @Override  
  2. public final int startActivity(IApplicationThread caller, String callingPackage,  
  3.         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,  
  4.         int startFlags, ProfilerInfo profilerInfo, Bundle options) {  
  5.     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,  
  6.         resultWho, requestCode, startFlags, profilerInfo, options,  
  7.         UserHandle.getCallingUserId());  
  8. }  
  9.   
  10. @Override  
  11. public final int startActivityAsUser(IApplicationThread caller, String callingPackage,  
  12.         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,  
  13.         int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {  
  14.     enforceNotIsolatedCaller("startActivity");  
  15.     userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,  
  16.             false, ALLOW_FULL_ONLY, "startActivity", null);  
  17.     // TODO: Switch to user app stacks here.  
  18.     return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,  
  19.             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,  
  20.             profilerInfo, null, null, options, userId, null, null);  
  21. }  

        ActivityStackSupervisor.class

[java] view plain copy

  1. final int startActivityMayWait(IApplicationThread caller, int callingUid,  
  2.         String callingPackage, Intent intent, String resolvedType,  
  3.         IVoiceInteractionSession voiceSession,  
  4.         IVoiceInteractor voiceInteractor, IBinder resultTo,  
  5.         String resultWho, int requestCode, int startFlags,  
  6.         ProfilerInfo profilerInfo, WaitResult outResult,  
  7.         Configuration config, Bundle options, int userId,  
  8.         IActivityContainer iContainer, TaskRecord inTask) {  
  9.     // Refuse possible leaked file descriptors  
  10.     if (intent != null && intent.hasFileDescriptors()) {  
  11.         throw new IllegalArgumentException(  
  12.                 "File descriptors passed in Intent");  
  13.     }  
  14.     // ...  
  15.   
  16.     if (aInfo != null  
  17.             && (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {  
  18.     // ...  
  19.     }  
  20.   
  21.     int res = startActivityLocked(caller, intent, resolvedType, aInfo,  
  22.             voiceSession, voiceInteractor, resultTo, resultWho,  
  23.             requestCode, callingPid, callingUid, callingPackage,  
  24.             realCallingPid, realCallingUid, startFlags, options,  
  25.             componentSpecified, null, container, inTask);  
  26.       
  27.     // ...  
  28.       
  29.     return res;  
  30. }  


        ActivityStackSupervisor 類是用來輔助管理ActivityStack的,在ActivityStackSupervisor中能夠看到

        ActivityStackSupervisor.class

[java] view plain copy

  1. /** The stack containing the launcher app. Assumed to always be attached to 
  2.  * Display.DEFAULT_DISPLAY. */  
  3. private ActivityStack mHomeStack;  
  4.   
  5. /** The stack currently receiving input or launching the next activity. */  
  6. private ActivityStack mFocusedStack;  
  7.   
  8. /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 
  9.  * been resumed. If stacks are changing position this will hold the old stack until the new 
  10.  * stack becomes resumed after which it will be set to mFocusedStack. */  
  11. 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

  1. final int startActivityLocked(IApplicationThread caller,  
  2.            Intent intent, String resolvedType, ActivityInfo aInfo,  
  3.            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,  
  4.            IBinder resultTo, String resultWho, int requestCode,  
  5.            int callingPid, int callingUid, String callingPackage,  
  6.            int realCallingPid, int realCallingUid, int startFlags, Bundle options,  
  7.            boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,  
  8.            TaskRecord inTask) {  
  9.        int err = ActivityManager.START_SUCCESS;  
  10.        ProcessRecord callerApp = null;  
  11.        if (caller != null) {  
  12.         //...  
  13.        }  
  14.        //...  
  15.       if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {  
  16.         //...  
  17.        }  
  18.   
  19.        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {  
  20.            // We couldn't find a class that can handle the given Intent.  
  21.            // That's the end of that!  
  22.            err = ActivityManager.START_INTENT_NOT_RESOLVED;  
  23.        }  
  24.          
  25.        if (err == ActivityManager.START_SUCCESS && aInfo == null) {  
  26.            // We couldn't find the specific class specified in the Intent.  
  27.            // Also the end of the line.  
  28.            err = ActivityManager.START_CLASS_NOT_FOUND;  
  29.        }  
  30.       //...          
  31.        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,  
  32.                startFlags, true, options, inTask);  
  33.       //...  
  34.        return err;  
  35.    }  

        主要是檢查目標APP或者Activity的一些信息,包括是否存在,是否擁有權限等,最後又會調用startActivityUncheckedLocked,此時目標Activity通過了經過了檢查。

        startActivityUncheckedLocked中又調用了targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options),這裏跟上面的ActivityStackSupervisor.startActivityLocked方法名相同。

        ActivityStack.class

[java] view plain copy

  1. final void startActivityLocked(ActivityRecord r, boolean newTask,  
  2.         boolean doResume, boolean keepCurTransition, Bundle options) {  
  3.     TaskRecord rTask = r.task;  
  4.     final int taskId = rTask.taskId;  
  5.     // mLaunchTaskBehind tasks get placed at the back of the task stack.  
  6.     if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {  
  7.         // Last activity in task had been removed or ActivityManagerService is reusing task.  
  8.         // Insert or replace.  
  9.         // Might not even be in.  
  10.         //若是是新任務,插入棧頂  
  11.         insertTaskAtTop(rTask);  
  12.         mWindowManager.moveTaskToTop(taskId);  
  13.     }  
  14.     TaskRecord task = null;  
  15.     if (!newTask) {  
  16.         // If starting in an existing task, find where that is...  
  17.         //若是不是是新任務  
  18.         boolean startIt = true;  
  19.         //遍歷mHistory  
  20.         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {  
  21.             task = mTaskHistory.get(taskNdx);  
  22.             if (task.getTopActivity() == null) {  
  23.                 // All activities in task are finishing.  
  24.                 continue;  
  25.             }  
  26.             if (task == r.task) {  
  27.                 // Here it is!  Now, if this is not yet visible to the  
  28.                 // user, then just add it without starting; it will  
  29.                 // get started when the user navigates back to it.  
  30.                 if (!startIt) {  
  31.                     if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "  
  32.                             + task, new RuntimeException("here").fillInStackTrace());  
  33.                     task.addActivityToTop(r);  
  34.                     r.putInHistory();  
  35.                     mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,  
  36.                             r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,  
  37.                             (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,  
  38.                             r.userId, r.info.configChanges, task.voiceSession != null,  
  39.                             r.mLaunchTaskBehind);  
  40.                     if (VALIDATE_TOKENS) {  
  41.                         validateAppTokensLocked();  
  42.                     }  
  43.                     ActivityOptions.abort(options);  
  44.                     return;  
  45.                 }  
  46.                 break;  
  47.             } else if (task.numFullscreen > 0) {  
  48.                 startIt = false;  
  49.             }  
  50.         }  
  51.     }  
  52.   
  53.     // Place a new activity at top of stack, so it is next to interact  
  54.     // with the user.  
  55.   
  56.     // If we are not placing the new activity frontmost, we do not want  
  57.     // to deliver the onUserLeaving callback to the actual frontmost  
  58.     // activity  
  59.     if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {  
  60.         //...   
  61.     }  
  62.   
  63.    //...   
  64.     if (!isHomeStack() || numActivities() > 0) {  
  65.         //...   
  66.     } else {  
  67.         //...   
  68.     }  
  69.     if (VALIDATE_TOKENS) {  
  70.         validateAppTokensLocked();  
  71.     }  
  72.   
  73.     if (doResume) {  
  74.         mStackSupervisor.resumeTopActivitiesLocked(this, r, options);  
  75.     }  
  76. }  

        在ActivityStackSupervisor.startActivityUncheckedLocked和ActivityStack.startActivityLocked主要是找到或建立合適的Task,根據FLAG_ACTIVITY_XX(啓動模式)進行不一樣的Task操做,這裏調度task的算法很複雜。
        上面執行完成以後,調用mStackSupervisor.resumeTopActivitiesLocked(this, r, options);ActivityStack

        ActivityStackSupervisor.class

[java] view plain copy

  1. boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,  
  2.         Bundle targetOptions) {  
  3.     if (targetStack == null) {  
  4.         targetStack = getFocusedStack();  
  5.     }  
  6.     // Do targetStack first.  
  7.     boolean result = false;  
  8.     if (isFrontStack(targetStack)) {  
  9.         result = targetStack.resumeTopActivityLocked(target, targetOptions);  
  10.     }  
  11.     for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {  
  12.         final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;  
  13.         for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  14.             final ActivityStack stack = stacks.get(stackNdx);  
  15.             if (stack == targetStack) {  
  16.                 // Already started above.  
  17.                 continue;  
  18.             }  
  19.             if (isFrontStack(stack)) {  
  20.                 stack.resumeTopActivityLocked(null);  
  21.             }  
  22.         }  
  23.     }  
  24.     return result;  
  25. }  

        ActivityStack.class

[java] view plain copy

  1. final boolean resumeTopActivityLocked(ActivityRecord prev) {  
  2.     return resumeTopActivityLocked(prev, null);  
  3. }  
  4.   
  5. final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {  
  6.     if (mStackSupervisor.inResumeTopActivity) {  
  7.         // Don't even start recursing.  
  8.         return false;  
  9.     }  
  10.   
  11.     boolean result = false;  
  12.     try {  
  13.         // Protect against recursion.  
  14.         mStackSupervisor.inResumeTopActivity = true;  
  15.         if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {  
  16.             mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;  
  17.             mService.updateSleepIfNeededLocked();  
  18.         }  
  19.         result = resumeTopActivityInnerLocked(prev, options);  
  20.     } finally {  
  21.         mStackSupervisor.inResumeTopActivity = false;  
  22.     }  
  23.     return result;  
  24. }  

        ActivityStack.class

        resumeTopActivityInnerLocked方法裏面代碼太多
[java] view plain copy

  1. final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {  
  2.     //...  
  3.   
  4.     // Find the first activity that is not finishing.  
  5.     //找到第一個沒有finish的activity,這個Activity就是Activity_A  
  6.     final ActivityRecord next = topRunningActivityLocked(null);  
  7.   
  8.     // Remember how we'll process this pause/resume situation, and ensure  
  9.     // that the state is reset however we wind up proceeding.  
  10.     final boolean userLeaving = mStackSupervisor.mUserLeaving;  
  11.     mStackSupervisor.mUserLeaving = false;  
  12.   
  13.     final TaskRecord prevTask = prev != null ? prev.task : null;  
  14.     //若是是開機啓動,則next==null,因此就是啓動Launcher了  
  15.     if (next == null) {  
  16.         // There are no more activities!  Let's just start up the  
  17.         // Launcher...  
  18.         ActivityOptions.abort(options);  
  19.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");  
  20.         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();  
  21.         // Only resume home if on home display  
  22.         final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?  
  23.                 HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();  
  24.         return isOnHomeDisplay() &&  
  25.                 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");  
  26.     }  
  27.   
  28.     
  29.     //...  
  30.     // We need to start pausing the current activity so the top one  
  31.     // can be resumed...  
  32.     //去 pause當前處於resumed狀態的Activity,也就是Activity_A  
  33.     boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;  
  34.     boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);  
  35.     if (mResumedActivity != null) {  
  36.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);  
  37.         pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);  
  38.     }  
  39.    //...  
  40.    if (prev != null && prev != next) {}  
  41.   
  42.    //...  
  43.   
  44.     return true;  
  45. }   

        這裏先分析Launcher的啓動函數 resumeHomeStackTask

        ActivityStackSupervisor.class

[java] view plain copy

  1. boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {  
  2.        if (!mService.mBooting && !mService.mBooted) {  
  3.            // Not ready yet!  
  4.            return false;  
  5.        }  
  6.   
  7.        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {  
  8.            mWindowManager.showRecentApps();  
  9.            return false;  
  10.        }  
  11.        moveHomeStackTaskToTop(homeStackTaskType, reason);  
  12.        if (prev != null) {  
  13.            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);  
  14.        }  
  15.   
  16.        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);  
  17.        // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {  
  18.        if (r != null && r.isHomeActivity()) {  
  19.            mService.setFocusedActivityLocked(r, reason);  
  20.            return resumeTopActivitiesLocked(mHomeStack, prev, null);  
  21.        }  
  22.        //啓動Launcher  
  23.        return mService.startHomeActivityLocked(mCurrentUser, reason);  
  24.    }  

        mService.startHomeActivityLocked(mCurrentUser, reason)啓動Launcher

        ActivityManagerService.class

[java] view plain copy

  1. boolean startHomeActivityLocked(int userId, String reason) {  
  2.     if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL  
  3.             && mTopAction == null) {  
  4.         // We are running in factory test mode, but unable to find  
  5.         // the factory test app, so just sit around displaying the  
  6.         // error message and don't try to start anything.  
  7.         return false;  
  8.     }  
  9.     Intent intent = getHomeIntent();  
  10.     ActivityInfo aInfo =  
  11.         resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);  
  12.     if (aInfo != null) {  
  13.         intent.setComponent(new ComponentName(  
  14.                 aInfo.applicationInfo.packageName, aInfo.name));  
  15.         // Don't do this if the home app is currently being  
  16.         // instrumented.  
  17.         aInfo = new ActivityInfo(aInfo);  
  18.         aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);  
  19.         ProcessRecord app = getProcessRecordLocked(aInfo.processName,  
  20.                 aInfo.applicationInfo.uid, true);  
  21.         if (app == null || app.instrumentationClass == null) {  
  22.             intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);  
  23.             mStackSupervisor.startHomeActivity(intent, aInfo, reason);  
  24.         }  
  25.     }  
  26.   
  27.     return true;  
  28. }  

        ActivityStackSupervisor.class

[java] view plain copy

  1. void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {  
  2.     moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);  
  3.     startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,  
  4.             0, 0, 0, null, false, null, null, null);  
  5. }     

         裏面也是調用了startActivityLocked,若是想定義本身的Launcher的話,貌似就能夠在這裏修改代碼了。

        再去追蹤startPausingLocked

        ActivityStack.class

[java] view plain copy

  1. final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,  
  2.         boolean dontWait) {  
  3.     if (mPausingActivity != null) {  
  4.         Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);  
  5.         completePauseLocked(false);  
  6.     }  
  7.     //prev包含了Activity_A,因此prev.app != null && prev.app.thread != null  
  8.     ActivityRecord prev = mResumedActivity;  
  9.     if (prev == null) {  
  10.         if (!resuming) {  
  11.             Slog.wtf(TAG, "Trying to pause when nothing is resumed");  
  12.             mStackSupervisor.resumeTopActivitiesLocked();  
  13.         }  
  14.         return false;  
  15.     }  
  16.     //...  
  17.     if (prev.app != null && prev.app.thread != null) {  
  18.         if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);  
  19.         try {  
  20.             EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,  
  21.                     prev.userId, System.identityHashCode(prev),  
  22.                     prev.shortComponentName);  
  23.             mService.updateUsageStats(prev, false);  
  24.             //這句是關鍵,經過Binder調用ActivityThread中的方法,AmS 會經過 IPC 調用到 ActivityThread 的schedulePauseActivity  
  25.             prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,  
  26.                     userLeaving, prev.configChangeFlags, dontWait);  
  27.         } catch (Exception e) {  
  28.             // Ignore exception, if process died other code will cleanup.  
  29.             Slog.w(TAG, "Exception thrown during pause", e);  
  30.             mPausingActivity = null;  
  31.             mLastPausedActivity = null;  
  32.             mLastNoHistoryActivity = null;  
  33.         }  
  34.     } else {  
  35.         mPausingActivity = null;  
  36.         mLastPausedActivity = null;  
  37.         mLastNoHistoryActivity = null;  
  38.     }  
  39.   
  40.      //...  
  41.         return false;  
  42.     }  

        疑問:爲何prev.app.thread.schedulePauseActivity能調用到ApplicationThread中的schedulePauseActivity方法?

        ----Binder機制,具體怎麼實現的我也沒弄明白。

        ActivityThread.class

        ApplicationThread是ActivityThread的一個內部類,有木有感受裏面的方法是那麼熟悉?

[java] view plain copy

  1. private class ApplicationThread extends ApplicationThreadNative {  
  2.    
  3.    //...  
  4.     public final void schedulePauseActivity(IBinder token, boolean finished,  
  5.             boolean userLeaving, int configChanges, boolean dontReport) {  
  6.         sendMessage(  
  7.                 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,  
  8.                 token,  
  9.                 (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),  
  10.                 configChanges);  
  11.     }  
  12.   
  13.     public final void scheduleStopActivity(IBinder token, boolean showWindow,  
  14.             int configChanges) {  
  15.        sendMessage(  
  16.             showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,  
  17.             token, 0, configChanges);  
  18.     }  
  19.   
  20.     public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {  
  21.         sendMessage(  
  22.             showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,  
  23.             token);  
  24.     }  
  25.   
  26.     public final void scheduleSleeping(IBinder token, boolean sleeping) {  
  27.         sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);  
  28.     }  
  29.   
  30.     public final void scheduleResumeActivity(IBinder token, int processState,  
  31.             boolean isForward, Bundle resumeArgs) {  
  32.         updateProcessState(processState, false);  
  33.         sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);  
  34.     }  
  35.   
  36.     public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {  
  37.         ResultData res = new ResultData();  
  38.         res.token = token;  
  39.         res.results = results;  
  40.         sendMessage(H.SEND_RESULT, res);  
  41.     }  
  42.   
  43.     // we use token to identify this activity without having to send the  
  44.     // activity itself back to the activity manager. (matters more with ipc)  
  45.     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,  
  46.             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,  
  47.             String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,  
  48.             PersistableBundle persistentState, List<ResultInfo> pendingResults,  
  49.             List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,  
  50.             ProfilerInfo profilerInfo) {  
  51.   
  52.         updateProcessState(procState, false);  
  53.   
  54.         ActivityClientRecord r = new ActivityClientRecord();  
  55.   
  56.         r.token = token;  
  57.         r.ident = ident;  
  58.         r.intent = intent;  
  59.         r.referrer = referrer;  
  60.         r.voiceInteractor = voiceInteractor;  
  61.         r.activityInfo = info;  
  62.         r.compatInfo = compatInfo;  
  63.         r.state = state;  
  64.         r.persistentState = persistentState;  
  65.   
  66.         r.pendingResults = pendingResults;  
  67.         r.pendingIntents = pendingNewIntents;  
  68.   
  69.         r.startsNotResumed = notResumed;  
  70.         r.isForward = isForward;  
  71.   
  72.         r.profilerInfo = profilerInfo;  
  73.   
  74.         updatePendingConfiguration(curConfig);  
  75.   
  76.         sendMessage(H.LAUNCH_ACTIVITY, r);  
  77.     }  
  78.   
  79.     public final void scheduleRelaunchActivity(IBinder token,  
  80.             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,  
  81.             int configChanges, boolean notResumed, Configuration config) {  
  82.         requestRelaunchActivity(token, pendingResults, pendingNewIntents,  
  83.                 configChanges, notResumed, config, true);  
  84.     }  
  85.   
  86.     public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {  
  87.         NewIntentData data = new NewIntentData();  
  88.         data.intents = intents;  
  89.         data.token = token;  
  90.   
  91.         sendMessage(H.NEW_INTENT, data);  
  92.     }  
  93.   
  94.     public final void scheduleDestroyActivity(IBinder token, boolean finishing,  
  95.             int configChanges) {  
  96.         sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,  
  97.                 configChanges);  
  98.     }  
  99.   
  100.     public final void scheduleReceiver(Intent intent, ActivityInfo info,  
  101.             CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,  
  102.             boolean sync, int sendingUser, int processState) {  
  103.         updateProcessState(processState, false);  
  104.         ReceiverData r = new ReceiverData(intent, resultCode, data, extras,  
  105.                 sync, false, mAppThread.asBinder(), sendingUser);  
  106.         r.info = info;  
  107.         r.compatInfo = compatInfo;  
  108.         sendMessage(H.RECEIVER, r);  
  109.     }  
  110.   
  111.    //...  
  112.     public final void scheduleCreateService(IBinder token,  
  113.             ServiceInfo info, CompatibilityInfo compatInfo, int processState) {  
  114.         updateProcessState(processState, false);  
  115.         CreateServiceData s = new CreateServiceData();  
  116.         s.token = token;  
  117.         s.info = info;  
  118.         s.compatInfo = compatInfo;  
  119.   
  120.         sendMessage(H.CREATE_SERVICE, s);  
  121.     }  
  122.   
  123.     public final void scheduleBindService(IBinder token, Intent intent,  
  124.             boolean rebind, int processState) {  
  125.         updateProcessState(processState, false);  
  126.         BindServiceData s = new BindServiceData();  
  127.         s.token = token;  
  128.         s.intent = intent;  
  129.         s.rebind = rebind;  
  130.   
  131.         if (DEBUG_SERVICE)  
  132.             Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="  
  133.                     + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());  
  134.         sendMessage(H.BIND_SERVICE, s);  
  135.     }  
  136.   
  137.     //...     
  138. }  

        schedulePauseActivity裏面有個H.PAUSE_ACTIVITY_FINISHING。
        前面說過,H也是ActivityThread的一個內部類,繼承Handler,用來處理Activty,Service等生命週期的回調消息。關於Handler Loopr的通訊原理,能夠參考一下之前寫過一篇博文《從Android源碼角度對Handler,MessageQueue,Looper之間消息傳遞工做原理的理解》
        ActivityThread.class
[java] view plain copy

  1. private class H extends Handler {  
  2.           
  3.     public void handleMessage(Message msg) {  
  4.         if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));  
  5.         switch (msg.what) {  
  6.             case LAUNCH_ACTIVITY: {  
  7.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");  
  8.                 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;  
  9.   
  10.                 r.packageInfo = getPackageInfoNoCheck(  
  11.                         r.activityInfo.applicationInfo, r.compatInfo);  
  12.                 handleLaunchActivity(r, null);  
  13.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  14.             } break;  
  15.             case RELAUNCH_ACTIVITY: {  
  16.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");  
  17.                 ActivityClientRecord r = (ActivityClientRecord)msg.obj;  
  18.                 handleRelaunchActivity(r);  
  19.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  20.             } break;  
  21.             case PAUSE_ACTIVITY:  
  22.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");  
  23.                 handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,  
  24.                         (msg.arg1&2) != 0);  
  25.                 maybeSnapshot();  
  26.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  27.                 break;  
  28.             case PAUSE_ACTIVITY_FINISHING:  
  29.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");  
  30.                 handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,  
  31.                         (msg.arg1&1) != 0);  
  32.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  33.                 break;  
  34.             case STOP_ACTIVITY_SHOW:  
  35.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");  
  36.                 handleStopActivity((IBinder)msg.obj, true, msg.arg2);  
  37.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  38.                 break;  
  39.             case STOP_ACTIVITY_HIDE:  
  40.                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");  
  41.                 handleStopActivity((IBinder)msg.obj, false, msg.arg2);  
  42.                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  43.                 break;  
  44.            //...       
  45.         }  


        ActivityThread.class

[java] view plain copy

  1. private void handlePauseActivity(IBinder token, boolean finished,  
  2.           boolean userLeaving, int configChanges, boolean dontReport) {  
  3.       ActivityClientRecord r = mActivities.get(token);  
  4.       if (r != null) {  
  5.           //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);  
  6.           if (userLeaving) {  
  7.               performUserLeavingActivity(r);  
  8.           }  
  9.   
  10.           r.activity.mConfigChangeFlags |= configChanges;  
  11.           performPauseActivity(token, finished, r.isPreHoneycomb());  
  12.   
  13.           // Make sure any pending writes are now committed.  
  14.           if (r.isPreHoneycomb()) {  
  15.               QueuedWork.waitToFinish();  
  16.           }  
  17.   
  18.           // Tell the activity manager we have paused.  
  19.           if (!dontReport) {  
  20.               try {  
  21.                   ActivityManagerNative.getDefault().activityPaused(token);  
  22.               } catch (RemoteException ex) {  
  23.               }  
  24.           }  
  25.           mSomeActivitiesChanged = true;  
  26.       }  
  27.   }  

        ActivityThread.class
[java] view plain copy

  1. final Bundle performPauseActivity(IBinder token, boolean finished,  
  2.         boolean saveState) {  
  3.     ActivityClientRecord r = mActivities.get(token);  
  4.     return r != null ? performPauseActivity(r, finished, saveState) : null;  
  5. }  
  6.   
  7.   
  8. final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,  
  9.         boolean saveState) {  
  10.     if (r.paused) {  
  11.        //...  
  12.     }  
  13.     if (finished) {  
  14.          //...  
  15.     }  
  16.     try {  
  17.         // Next have the activity save its current state and managed dialogs...  
  18.         //通知Activity_A調用onSaveInstanceState保存狀態  
  19.         if (!r.activity.mFinished && saveState) {  
  20.             callCallActivityOnSaveInstanceState(r);  
  21.         }  
  22.         // Now we are idle.  
  23.       //通知Activity_A調用OnPause方法  
  24.         r.activity.mCalled = false;  
  25.         mInstrumentation.callActivityOnPause(r.activity);  
  26.         EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),  
  27.                 r.activity.getComponentName().getClassName());  
  28.         if (!r.activity.mCalled) {  
  29.             throw new SuperNotCalledException(  
  30.                 "Activity " + r.intent.getComponent().toShortString() +  
  31.                 " did not call through to super.onPause()");  
  32.         }  
  33.   
  34.     } catch (SuperNotCalledException e) {  
  35.         throw e;  
  36.   
  37.     } catch (Exception e) {  
  38.         //...  
  39.     }  
  40.     r.paused = true;  
  41.     return !r.activity.mFinished && saveState ? r.state : null;  
  42. }  

        在這裏終於明白了,在啓動目標Activity前,若是當前正在運行任何Activity,那麼必須首先暫停。

        追蹤mInstrumentation.callActivityOnPause(r.activity)

        Instrumentation.class

[java] view plain copy

  1. public void callActivityOnPause(Activity activity) {  
  2.     activity.performPause();  
  3. }  

        Activity.class

[java] view plain copy

  1. final void performPause() {  
  2.     mDoReportFullyDrawn = false;  
  3.     mFragments.dispatchPause();  
  4.     mCalled = false;  
  5.     onPause();  
  6.     mResumed = false;  
  7.     if (!mCalled && getApplicationInfo().targetSdkVersion  
  8.             >= android.os.Build.VERSION_CODES.GINGERBREAD) {  
  9.         throw new SuperNotCalledException(  
  10.                 "Activity " + mComponent.toShortString() +  
  11.                 " did not call through to super.onPause()");  
  12.     }  
  13.     mResumed = false;  
  14. }  

        終於看到了Activity的onPause方法,至此,Activity_A已經執行onPause方法,Activity_B未執行其生命週期的任何方法。

        在下一篇中將繼續去追蹤Activity_B生命週期回調源碼。

相關文章
相關標籤/搜索