【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 一 )
文章目錄
- 一、ActivityThread 主函數(shù)啟動(dòng)
- 二、ActivityThread 綁定 ApplicationThread
- 三、AMS attachApplication -> attachApplicationLocked 綁定 ApplicationThread
- 四、ApplicationThread.bindApplication 綁定 ApplicationThread
- 五、ActivityThread.H 處理 BIND_APPLICATION 消息
- 六、ActivityThread.handleBindApplication 處理綁定問題
- 七、LoadedApk.makeApplication 創(chuàng)建 Application 對(duì)象
- 八、Instrumentation.newApplication 創(chuàng)建 Application 對(duì)象
- 九、AppComponentFactory.instantiateApplicationCompat 創(chuàng)建 Application 對(duì)象
一、ActivityThread 主函數(shù)啟動(dòng)
ActivityThread 是應(yīng)用的主線程 , 從 main 函數(shù)開始執(zhí)行 ;
Looper.prepareMainLooper() 將主線程設(shè)置為 Looper 線程 , 開啟 Looper , 用于配合 H 處理消息 ;
thread.attach(false, startSeq) 綁定 ActivityThread ;
在方法最后 Looper.loop(); 開始無限循環(huán) , 處理 Handler 消息 ;
/*** 管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行、調(diào)度和執(zhí)行活動(dòng)、廣播以及活動(dòng)管理器請(qǐng)求的其他操作。** {@hide}*/ public final class ActivityThread extends ClientTransactionHandler {public static void main(String[] args) {// 將主線程設(shè)置為 Looper 線程 , 開啟 Looper , 用于配合 H 處理消息 Looper.prepareMainLooper();// 創(chuàng)建 ActivityThread 實(shí)例對(duì)象 ActivityThread thread = new ActivityThread();// 綁定thread.attach(false, startSeq);// 開始無限循環(huán) , 處理 Handler 消息 Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");} }完整代碼參考 /frameworks/base/core/java/android/app/ActivityThread.java
二、ActivityThread 綁定 ApplicationThread
ActivityThread 中的 void attach(boolean system, long startSeq) 方法 , 主要是通過 Binder 機(jī)制獲取 AMS , 并調(diào)用 AMS 的 attachApplication 方法 , 為 ActivityThread 綁定 ApplicationThread ;
/*** 管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行、調(diào)度和執(zhí)行活動(dòng)、廣播以及活動(dòng)管理器請(qǐng)求的其他操作。** {@hide}*/ public final class ActivityThread extends ClientTransactionHandler {private void attach(boolean system, long startSeq) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {RuntimeInit.setApplicationObject(mAppThread.asBinder());// 通過 Binder 機(jī)制獲取 AMS final IActivityManager mgr = ActivityManager.getService();try {// 調(diào)用 AMS 的 attachApplication 方法 , 為 ActivityThread 綁定 ApplicationThread mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}}}完整代碼參考 /frameworks/base/core/java/android/app/ActivityThread.java
三、AMS attachApplication -> attachApplicationLocked 綁定 ApplicationThread
在 AMS 中的 attachApplication 方法中 , 調(diào)用了 attachApplicationLocked 方法 ,
在 attachApplicationLocked 方法中 , 有調(diào)用了 ActivityThread 的 bindApplication 方法 , 為 ActivityThread 綁定了 ApplicationThread ;
public class ActivityManagerService extends IActivityManager.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {@Overridepublic final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}}// 為 ApplicationThread 綁定 Application 主方法private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {try {checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);// 在此處為 ActivityThread 綁定 Application , 此時(shí)又回到 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) {}return true;}}ActivityManagerService 完整源碼參考 : frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
四、ApplicationThread.bindApplication 綁定 ApplicationThread
再次回到 ActivityThread 內(nèi)部類 ApplicationThread 中 , 調(diào)用 ApplicationThread 類的 bindApplication 方法 , 即可為 ActivityThread 綁定 ApplicationThread , 在所有數(shù)據(jù)就位后 , 發(fā)送了一個(gè) H.BIND_APPLICATION 消息 ;
/*** 管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行、調(diào)度和執(zhí)行活動(dòng)、廣播以及活動(dòng)管理器請(qǐng)求的其他操作。** {@hide}*/ public final class ActivityThread extends ClientTransactionHandler {private class ApplicationThread extends IApplicationThread.Stub {// 為 ActivityThread 綁定 Application public final void bindApplication(String processName, ApplicationInfo appInfo,List<ProviderInfo> providers, ComponentName instrumentationName,ProfilerInfo profilerInfo, Bundle instrumentationArgs,IInstrumentationWatcher instrumentationWatcher,IUiAutomationConnection instrumentationUiConnection, int debugMode,boolean enableBinderTracking, boolean trackAllocation,boolean isRestrictedBackupMode, boolean persistent, Configuration config,CompatibilityInfo compatInfo, Map services, Bundle coreSettings,String buildSerial, boolean autofillCompatibilityEnabled) {// 此處在所有數(shù)據(jù)就位后 , 發(fā)送了一個(gè) H.BIND_APPLICATION 消息sendMessage(H.BIND_APPLICATION, data);}} }完整代碼參考 /frameworks/base/core/java/android/app/ActivityThread.java
五、ActivityThread.H 處理 BIND_APPLICATION 消息
在 ActivityThread.ApplicationThread.bindApplication 中 , 發(fā)送了一條 BIND_APPLICATION 消息 , 110110110 ;
在 ActivityThread.H 中的 handleMessage 方法中 , 處理 110110110 事件的分支中, 調(diào)用了 handleBindApplication 方法 , 處理綁定 ApplicationThread 相關(guān)邏輯 ;
/*** 管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行、調(diào)度和執(zhí)行活動(dòng)、廣播以及活動(dòng)管理器請(qǐng)求的其他操作。** {@hide}*/ public final class ActivityThread extends ClientTransactionHandler {class H extends Handler {public static final int BIND_APPLICATION = 110;public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");AppBindData data = (AppBindData)msg.obj;// 處理綁定 Application 相關(guān)邏輯handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;}Object obj = msg.obj;if (obj instanceof SomeArgs) {((SomeArgs) obj).recycle();}}} }完整代碼參考 /frameworks/base/core/java/android/app/ActivityThread.java
六、ActivityThread.handleBindApplication 處理綁定問題
在 ActivityThread.handleBindApplication 方法中 , 通過調(diào)用 data.info.makeApplication(data.restrictedBackupMode, null) 方法 , 創(chuàng)建 Application 實(shí)例對(duì)象 ;
data.info 是 LoadedApk 類型 ;
/*** 管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行、調(diào)度和執(zhí)行活動(dòng)、廣播以及活動(dòng)管理器請(qǐng)求的其他操作。** {@hide}*/ public final class ActivityThread extends ClientTransactionHandler {private void handleBindApplication(AppBindData data) {// 將UI線程注冊(cè)為運(yùn)行時(shí)的敏感線程。VMRuntime.registerSensitiveThread();if (data.trackAllocation) {DdmVmInternal.enableRecentAllocations(true);}// 記錄進(jìn)程開始時(shí)間Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());// 允許在應(yīng)用程序和提供程序安裝期間訪問磁盤。// 這可能會(huì)阻止處理有序的廣播,但稍后的處理可能最終會(huì)執(zhí)行相同的磁盤訪問。Application app;final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();try {// 如果要啟動(dòng)應(yīng)用程序進(jìn)行完全備份或恢復(fù),請(qǐng)使用基本應(yīng)用程序類在受限環(huán)境中啟動(dòng)。app = data.info.makeApplication(data.restrictedBackupMode, null);// Propagate autofill compat stateapp.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);mInitialApplication = app;} } }完整代碼參考 /frameworks/base/core/java/android/app/ActivityThread.java
七、LoadedApk.makeApplication 創(chuàng)建 Application 對(duì)象
調(diào)用 LoadedApk 的 makeApplication 方法 , 創(chuàng)建 Application 實(shí)例 , 在該方法中通過調(diào)用 Instrumentation 的 newApplication 方法 , 創(chuàng)建 Application 實(shí)例對(duì)象
/*** 本地狀態(tài)維護(hù)了當(dāng)前加載的.apk. * Local state maintained about a currently loaded .apk.* @hide*/ public final class LoadedApk {// 創(chuàng)建 Application 實(shí)例對(duì)象 public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {// 如果當(dāng)前存在 Application , 直接返回 if (mApplication != null) {return mApplication;}try {ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// 通過調(diào)用 Instrumentation 的 newApplication 方法 , 創(chuàng)建 Application 實(shí)例對(duì)象app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {}mActivityThread.mAllApplications.add(app);mApplication = app;return app;} }完整代碼參考 /frameworks/base/core/java/android/app/LoadedApk.java ;
八、Instrumentation.newApplication 創(chuàng)建 Application 對(duì)象
在 LoadedApk 的 makeApplication 方法 中 , 調(diào)用了 Instrumentation 的 newApplication 方法創(chuàng)建 Application 實(shí)例對(duì)象 ;
/*** 用于實(shí)現(xiàn)應(yīng)用程序檢測(cè)代碼的基類。* 當(dāng)在啟用檢測(cè)的情況下運(yùn)行時(shí),該類將在任何應(yīng)用程序代碼之前為您實(shí)例化,* 從而允許您監(jiān)視系統(tǒng)與應(yīng)用程序之間的所有交互。* 通過AndroidManifest.xml的&lt;儀器儀表&gt;標(biāo)簽。*/ public class Instrumentation {/*** 執(zhí)行進(jìn)程{@link Application}對(duì)象的實(shí)例化。默認(rèn)實(shí)現(xiàn)提供正常的系統(tǒng)行為。** @param cl 用來實(shí)例化對(duì)象的類加載器。* @param className 實(shí)現(xiàn)應(yīng)用程序?qū)ο蟮念惖拿Q。* @param context 用于初始化應(yīng)用程序的上下文** @return 新實(shí)例化的應(yīng)用程序?qū)ο蟆?/public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException,ClassNotFoundException {Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);return app;}}完整代碼參考 /frameworks/base/core/java/android/app/Instrumentation.java ;
九、AppComponentFactory.instantiateApplicationCompat 創(chuàng)建 Application 對(duì)象
在 Instrumentation 的 newApplication 方法中 , 調(diào)用了 AppComponentFactory 的 instantiateApplicationCompat 方法 , 創(chuàng)建 Application , (Application) cl.loadClass(className).getDeclaredConstructor().newInstance(); , 此處通過反射創(chuàng)建 Application 實(shí)例對(duì)象 ;
/*** 使用androidx庫的{@link android.app.AppComponentFactory}版本。** 注意:這只適用于API 28+,不支持AppComponentFactory功能。*/ @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {/*** 允許應(yīng)用程序重寫應(yīng)用程序?qū)ο蟮膭?chuàng)建。這可以用于對(duì)這些類執(zhí)行依賴項(xiàng)注入或類裝入器更改等操作。* <p>* 此方法僅用于提供用于實(shí)例化的掛鉤。它不提供對(duì)應(yīng)用程序?qū)ο蟮脑缙谠L問。* 返回的對(duì)象尚未初始化為上下文,不應(yīng)用于與其他android API交互。** @param cl 用于實(shí)例化的默認(rèn)類加載器。* @param className 要實(shí)例化的類。*/public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl,@NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {try {return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();} catch (InvocationTargetException | NoSuchMethodException e) {throw new RuntimeException("Couldn't call constructor", e);}}}完整代碼參考 /frameworks/support/compat/src/main/java/androidx/core/app/AppComponentFactory.java ;
總結(jié)
以上是生活随笔為你收集整理的【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 一 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 启动过程】Activi
- 下一篇: 【Android 启动过程】Activi