【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 一 )(二)

简介: 【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 一 )(二)

五、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 ;


目录
相关文章
|
3月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
97 6
|
3月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
3月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
34 3
|
3月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
29 2
|
3月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
23 0
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
27天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
53 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
27天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
56 14
|
30天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。