五、ActivityThread.H 处理 BIND_APPLICATION 消息
在 ActivityThread.ApplicationThread.bindApplication 中 , 发送了一条 BIND_APPLICATION 消息 , 110 110110 ;
在 ActivityThread.H 中的 handleMessage 方法中 , 处理 110 110110 事件的分支中, 调用了 handleBindApplication 方法 , 处理绑定 ApplicationThread 相关逻辑 ;
/** * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。 * * {@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 相关逻辑 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 方法中 , 通过调用 data.info.makeApplication(data.restrictedBackupMode, null) 方法 , 创建 Application 实例对象 ;
data.info 是 LoadedApk 类型 ;
/** * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。 * * {@hide} */ public final class ActivityThread extends ClientTransactionHandler { private void handleBindApplication(AppBindData data) { // 将UI线程注册为运行时的敏感线程。 VMRuntime.registerSensitiveThread(); if (data.trackAllocation) { DdmVmInternal.enableRecentAllocations(true); } // 记录进程开始时间 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); // 允许在应用程序和提供程序安装期间访问磁盘。 // 这可能会阻止处理有序的广播,但稍后的处理可能最终会执行相同的磁盘访问。 Application app; final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy(); try { // 如果要启动应用程序进行完全备份或恢复,请使用基本应用程序类在受限环境中启动。 app = data.info.makeApplication(data.restrictedBackupMode, null); // Propagate autofill compat state app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled); mInitialApplication = app; } } }
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
七、LoadedApk.makeApplication 创建 Application 对象
调用 LoadedApk 的 makeApplication 方法 , 创建 Application 实例 , 在该方法中通过调用 Instrumentation 的 newApplication 方法 , 创建 Application 实例对象
/** * 本地状态维护了当前加载的.apk. * Local state maintained about a currently loaded .apk. * @hide */ public final class LoadedApk { // 创建 Application 实例对象 public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { // 如果当前存在 Application , 直接返回 if (mApplication != null) { return mApplication; } try { ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 通过调用 Instrumentation 的 newApplication 方法 , 创建 Application 实例对象 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 创建 Application 对象
在 LoadedApk 的 makeApplication 方法 中 , 调用了 Instrumentation 的 newApplication 方法创建 Application 实例对象 ;
/** * 用于实现应用程序检测代码的基类。 * 当在启用检测的情况下运行时,该类将在任何应用程序代码之前为您实例化, * 从而允许您监视系统与应用程序之间的所有交互。 * 通过AndroidManifest.xml的<仪器仪表>标签。 */ public class Instrumentation { /** * 执行进程{@link Application}对象的实例化。默认实现提供正常的系统行为。 * * @param cl 用来实例化对象的类加载器。 * @param className 实现应用程序对象的类的名称。 * @param context 用于初始化应用程序的上下文 * * @return 新实例化的应用程序对象。 */ 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 创建 Application 对象
在 Instrumentation 的 newApplication 方法中 , 调用了 AppComponentFactory 的 instantiateApplicationCompat 方法 , 创建 Application , (Application) cl.loadClass(className).getDeclaredConstructor().newInstance(); , 此处通过反射创建 Application 实例对象 ;
/** * 使用androidx库的{@link android.app.AppComponentFactory}版本。 * * 注意:这只适用于API 28+,不支持AppComponentFactory功能。 */ @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory { /** * 允许应用程序重写应用程序对象的创建。这可以用于对这些类执行依赖项注入或类装入器更改等操作。 * <p> * 此方法仅用于提供用于实例化的挂钩。它不提供对应用程序对象的早期访问。 * 返回的对象尚未初始化为上下文,不应用于与其他android API交互。 * * @param cl 用于实例化的默认类加载器。 * @param className 要实例化的类。 */ 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 ;