探索7.x, 全面解析Activity启动框架 (2)
本文是探索Activity啟動源碼的第二篇, 其余參考第一篇.
Activity
第一篇的流程圖:
流程圖
第一篇已經探索至關鍵位置, 即ActivityStackSupervisor的realStartActivityLocked方法, 方法如其名, 從此開始, 才是真正地(Real)啟動(Start). Let's start!
ActivityManagerService
ActivityStackSupervisor#realStartActivityLocked:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {// 當屏幕方向修改時, 推遲恢復, 防止冗余啟動Activity.if (checkConfig) {Configuration config = mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration,r.mayFreezeScreenLocked(app) ? r.appToken : null);mService.updateConfigurationLocked(config, r, false, true /* deferResume */);}// 將進程描述符(ProcessRecord)設置入Activity描述符(ActivityRecord)r.app = app;app.waitingToKill = null; // 避免在后臺被殺死r.launchCount++; // 增加啟動次數r.lastLaunchTime = SystemClock.uptimeMillis(); // 最新啟動時間// 當Activity描述符不在進程的Activity列表中, 將Activity添加入進程的Activity列表int idx = app.activities.indexOf(r);if (idx < 0) {app.activities.add(r);}// AMS更新進程描述符為最少最新使用(LRU).mService.updateLruProcessLocked(app, true, null); // ...try {// ...// 遠程調用ApplicationThread的scheduleLaunchActivityapp.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);// ...} catch (RemoteException e) {// ...}// ...return true; }ActivityRecord即Activity描述符(變量r), 含有被啟動的Activity信息;?ProcessRecord即進程描述符(變量app), 含有當前應用的進程信息.
app.thread類型是IApplicationThread, 通過IApplicationThread的代理ApplicationThreadProxy, 遠程調用ApplicationThread的scheduleLaunchActivity方法, ApplicationThread是IApplicationThread的最終實現.
啟動Activity再次由AMS(ActivityManagerService)通過遠程調用(Binder)交給應用進程(ActivityThread)處理. ApplicationThread是ActivityThread的私有類.
ApplicationThread#scheduleLaunchActivity:
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {// ...// 即來自客戶端(AMS)的Activity描述符ActivityClientRecord r = new ActivityClientRecord();// 將AMS的Activity描述符, 轉換為當前進程的Activity描述符r.token = token;// ...// 封裝, 發送啟動消息給H類處理, 并傳遞Activity描述符sendMessage(H.LAUNCH_ACTIVITY, r); }sendMessage是重載方法, 最終調用H類處理數據.
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {// ...// 最終由H類(Handler)處理數據mH.sendMessage(msg); }將啟動Activity交給ActivityThread的Handler?H類處理.
private class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = (ActivityClientRecord)msg.obj;// 設置Activity描述符的包信息r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);// 至此, 完成啟動Activity已經由AMS交給當前應用, 在當前應用中啟動Activity.handleLaunchActivity(r, null);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;}} }啟動Activity, 先由當前進程, 通過ActivityManagerNative#getDefault#startActivity方法, 交給AMS處理, AMS管理Activity的Stack和Task, 并設置Activity描述符(Record); 再通過app.thread#scheduleLaunchActivity方法, 繼續交給當前進程處理.
AMS切換當前線程的流程圖:
流程圖
ActivityThread
ActivityThread#handleLaunchActivity:
handleLaunchActivity調用performLaunchActivity方法, 繼續執行啟動, 在成功后, 調用handleResumeActivity方法, 執行顯示Activity.
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {// 因為當前進程正在活躍, 所以跳過在后臺中執行GC.unscheduleGcIdler();// ...// 確保使用最近的環境配置handleConfigurationChanged(null, null);if (localLOGV) Slog.v(TAG, "Handling launch of " + r);// 在創建Activity前, 初始化WindowManagerGlobal, 即WindowManagerServiceWindowManagerGlobal.initialize();// 執行啟動ActivityActivity a = performLaunchActivity(r, customIntent);// 在啟動成功后, 處理恢復Activityif (a != null) {r.createdConfig = new Configuration(mConfiguration);reportSizeConfigurations(r);Bundle oldState = r.state;// 恢復ActivityhandleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);// ...}} else {// 如果發生錯誤, 則AMS停止啟動Activitytry {ActivityManagerNative.getDefault().finishActivity(r.token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}}ActivityThread#performLaunchActivity:
performLaunchActivity方法是Activity啟動的核心:
onPostCreate: Called when activity start-up is complete (after onStart() and onRestoreInstanceState(Bundle) have been called). Applications will generally not implement this method; it is intended for system classes to do final initialization after application code has run.
在調用時, 表明Activity已經完全啟動, 只剩下顯示(onResume).
通過分析performLaunchActivity, 我們也更加清晰Activity的生命周期, 順序如下, onCreate, onStart, onRestoreInstanceState, onPostCreate.?注意, onStart是Activity處理; 其余三個是Instrumentation處理, 支持繼承重寫相應方法, 自行處理.
至此, Activity已經完全啟動, 并調用相應的生命周期方法.
OK, that's all! Enjoy it!
原文地址:?http://www.jianshu.com/p/574d7d3fa34f總結
以上是生活随笔為你收集整理的探索7.x, 全面解析Activity启动框架 (2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 探索7.x, 全面解析Activity启
- 下一篇: 实现AIDL接口的Binder连接池