App啟動過程
概要
Android系統中每個app程序都是由zygote程序fork的子程序,fork之後會進行一些程序初始化工作比如binder設定等。。。完成這些初始化工作之後會進入ActivityThread.main方法中,從這裡開始會涉及Application、Activity的建立等一些列任務,這篇文章主要細說一下ActivityThread.main及其後續流程。
注:本流程是從api=27原始碼分析
ActivityThread.main
主要完成主執行緒Looper的建立開始迴圈等待事件,建立application,attach到ams中。
... Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); ... Looper.loop(); ...
ActivityThread.attach方法
... // 將ActivityThread中的成員變數ApplicationThread傳遞給ams mgr.attachApplication(mAppThread); ... // 值得注意的是在這裡還監控了下當前系統記憶體已經使用的大小是否大於總大小的四分之三,如果超過了,則系統會釋放一些Activity。 ... BinderInternal.addGcWatcher(new Runnable() { @Override public void run() { if (!mSomeActivitiesChanged) { return; } Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.maxMemory(); long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); if (dalvikUsed > ((3*dalvikMax)/4)) { if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) + " total=" + (runtime.totalMemory()/1024) + " used=" + (dalvikUsed/1024)); mSomeActivitiesChanged = false; try { mgr.releaseSomeActivities(mAppThread); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } }); ...
到此為止我們的流程從app程序轉向ams所在程序,ActivityManagerService.attachApplication主要實現在attachApplicationLocked方法中。
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ... 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); ... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } } ...
thread.bindApplication 遠端呼叫了app程序中的 ApplicationThread.bindApplication -> ActivityThread.handleBindApplication
private void handleBindApplication(AppBindData data) { ... // 由 LoadApk 類完成 Application 的建立 Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; ...
我們再回到ams程序中,ActivityManagerService.attachApplication,thread.bindApplication 執行完後,會接著執行下面程式碼
... // mStackSupervisor 注意該欄位,屬於ams成員變數,管理所有 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; } } ...
mStackSupervisor.attachApplicationLocked(app) -> ActivityStackSuperivisor.realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... // 又回到了 app程序,ApplicationThread.scheduleLaunchActivity app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 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, !andResume, mService.isNextTransitionForward(), profilerInfo); ...
隨後即進入 app 程序中,ActivityThread.handleLaunchActivity,其中呼叫了兩個方法 performLaunchActivity 和 handleResumeActivity 分別對應呼叫 onCreate 和 onReusme,完成 Activity 的建立及其視窗進入。
ActivityThread.performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... try { java.lang.ClassLoader cl = appContext.getClassLoader(); // 利用 ClasssLoader 建立 Activity 例項 activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } ... ... // 利用 Instrumentation 類完成 Activity 的建立,也是在這一步對應回撥我們熟悉的 onCreate 方法 activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ... }
ActivityThread.handleResumeActivity 中的核心方法 performResumeActivity
r = performResumeActivity(token, clearHide, reason);
ActivityThread.performResumeActivity
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) { ... // 最終還是由 Instrumentation 完成 onStart onResume 的回撥 r.activity.performResume(); ...
由此可見 Activity 的所有生命週期的回撥都是由 ActivityThread.mInstrumentation 來完成的
自此已經從 AcitivityThread.main 分析到了 LAUNCHER Activity onCreate onStart onResume,後面的分析待續...