【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 二 )
文章目錄
- 前言
- 一、ActivityManagerService.attachApplicationLocked
- 二、ActivityStackSupervisor.attachApplicationLocked
- 三、ActivityStackSupervisor.realStartActivityLocked
前言
在上一篇博客 【Android 啟動過程】Activity 啟動源碼分析 ( ActivityThread 流程分析 一 ) 分析了從 ActivityThread 的 main() 函數啟動 , ApplicationThread 綁定 , Application 創建 , 下面繼續分析后續內容 ;
一、ActivityManagerService.attachApplicationLocked
回到 AMS 中的 ActivityManagerService 方法 , 在調用 ActivityThread 綁定 ApplicationThread 后 ,
有調用了 mStackSupervisor.attachApplicationLocked 方法 , 查看頂部可見 Activity 是否正等待在此進程中運行 ;
public class ActivityManagerService extends IActivityManager.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {// 為 ActivityThread 綁定 ApplicationThread 主方法private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {try {checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);// 在此處為 ActivityThread 綁定 ApplicationThread , 此時又回到 ActivityThreadif (app.instr != null) {thread.bindApplication(processName, appInfo, providers,app.instr.mClass,profilerInfo, app.instr.mArguments,app.instr.mWatcher,app.instr.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial);} else {thread.bindApplication(processName, appInfo, providers, null, profilerInfo,null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial);}} catch (Exception e) {}// 查看頂部可見 Activity 是否正在等待在此進程中運行if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}return true;}}ActivityManagerService 完整源碼參考 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
二、ActivityStackSupervisor.attachApplicationLocked
在上述 AMS 中的 attachApplicationLocked 方法中 , 調用了 ActivityStackSupervisor 的 attachApplicationLocked 方法 ,
在 ActivityStackSupervisor.attachApplicationLocked 方法中 , 調用了 ActivityStackSupervisor.realStartActivityLocked 方法 ;
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,RecentTasks.Callbacks {boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {// 省略其它代碼 , 在此處調用了 realStartActivityLocked 方法 if (realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {didSomething = true;}return didSomething;} }完整代碼參考 /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ;
三、ActivityStackSupervisor.realStartActivityLocked
該方法步驟在 【Android 啟動過程】Activity 啟動源碼分析 ( AMS -> ActivityThread、AMS 線程階段 二 ) 二、AMS 進程中執行的相關操作 章節進行過講解 , 不管是冷啟動 , 還是熱啟動 , 都要調用 ActivityStackSupervisor.realStartActivityLocked 方法開啟 Activity ;
后續邏輯基本就與該博客后續的分析對應上了 ;
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,RecentTasks.Callbacks {final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {if (!allPausedActivitiesComplete()) {// 當有活動暫停時,我們將跳過開始任何新活動,直到暫停完成。// 注意:對于在暫停狀態下啟動的活動,我們也會這樣做,因為它們將首先恢復,然后在客戶端暫停。if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,"realStartActivityLocked: Skipping start of r=" + r+ " some activities pausing...");return false;}final TaskRecord task = r.getTask();final ActivityStack stack = task.getStack();beginDeferResume();try {r.startFreezingScreenLocked(app, 0);// 安排啟動時間以收集有關慢速應用程序的信息。r.startLaunchTickingLocked();r.setProcess(app);if (getKeyguardController().isKeyguardLocked()) {r.notifyUnknownVisibilityLaunched();}// 讓窗口管理器根據新的活動順序重新評估屏幕方向。// 注意,這樣做的結果是,它可以使用新的方向調用activity manager。// 我們不關心這一點,因為活動當前未運行,所以我們只是重新啟動它。if (checkConfig) {// 推遲恢復,因為我們將很快啟動新活動。// 我們不希望在確保配置和嘗試恢復重點堆棧的頂級活動的同時,重復啟動同一記錄。ensureVisibilityAndConfig(r, r.getDisplayId(),false /* markFrozenIfConfigChanged */, true /* deferResume */);}if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,true /* isTop */)) {// 僅當基于keyguard狀態允許活動可見時,我們才將可見性設置為true。// 這樣可以避免在窗口管理器中將此設置為運動狀態,// 而由于以后的調用而取消該設置,以確保將可見性設置回false的可見活動。r.setVisibility(true);}try {// 下面的代碼是啟動 Activity 的核心代碼// Create activity launch transaction.final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,r.appToken);clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,// TODO: Have this take the merged configuration instead of separate global// and override configs.mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results, newIntents, mService.isNextTransitionForward(),profilerInfo));// 設置所需的最終狀態。配置生命周期final ActivityLifecycleItem lifecycleItem;if (andResume) {// 開啟新的 ActivitylifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());} else {// 終止 ActivitylifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// 安排事務。mService.getLifecycleManager().scheduleTransaction(clientTransaction);// 上面的代碼是啟動 Activity 的核心代碼} catch (RemoteException e) {}} finally {endDeferResume();}return true;} }完整代碼參考 /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ;
總結
以上是生活随笔為你收集整理的【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 二 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 启动过程】Activi
- 下一篇: 【Java 虚拟机原理】Dalvik 虚