Jetpack之App Startup的使用和不足,及改进版Android | 您所在的位置:网站首页 › startup用法 › Jetpack之App Startup的使用和不足,及改进版Android |
2020 年 10 月 28 日,JetPack | App Startup 1.0.0 终于迎来正式发布. 应用程序启动库提供了一种在应用程序启动时初始化组件的简单、高效的方法。库开发人员和应用程序开发人员都可以使用应用程序启动来简化启动顺序,并显式设置初始化顺序。 App Startup不需要为每个需要初始化的组件定义单独的内容提供程序,而是允许您定义共享单个内容提供程序的组件初始化程序。这可以显著缩短应用程序启动时间。 目录这篇文章的内容会涉及以下前置 / 相关知识,贴心的我都帮你准备好了,请享用~ ContentProvider 组件解析: Android | ContentProvider 的工作过程 1. 为什么要使用 App Startup?这一节,我们来讨论为什么要使用 App Startup ,也就是 App Startup 解决了什么问题。 基于 ContentProvider 启动机制实现的无侵入获取 Contex 的方法:《Android | 使用 ContentProvider 无侵入获取 Context》。在这里我简单复述一下: 1、在二方库或三方库中,经常需要获取 Context 进行初始化;2、因为 ContentProvider 会在应用启动的时候初始化,所以很多库都利用了 ContentProvider 的启动机制,在 Application#onCreate()中进行初始化,例如 LeakCanary 2.4:AppWatcherInstaller.java internal sealed class AppWatcherInstaller : ContentProvider() { internal class MainProcess : AppWatcherInstaller() internal class LeakCanaryProcess : AppWatcherInstaller() override fun onCreate(): Boolean { val application = context!!.applicationContext as Application AppWatcher.manualInstall(application) return true } // 其他方法直接 return } 3、这种做法的风险是 ContentProvider 过多,启动过多的 ContentProvider 会增加应用的启动时间。![]() ![]() 这一节,我们来总结 App Startup 的使用步骤,依赖如下: build.gradle implementation "androidx.startup:startup-runtime:1.0.0"2.1 为组件实现 Initializer 接口 Initializer接口是 Startup 封装的组件接口,用于指定组件的初始化逻辑和初始化顺序(也就是依赖关系)。 Initializer.java public interface Initializer { 1、初始化操作,返回的初始化结果将被缓存 @NonNull T create(@NonNull Context context); 2、依赖关系,返回值是一个依赖组件的列表 @NonNull List>> mDiscovered; 已简化 void discoverAndInitialize() { 1、获取 androidx.startup.InitializationProvider 组件信息 ComponentName provider = new ComponentName(mContext.getPackageName(), InitializationProvider.class.getName()); ProviderInfo providerInfo = mContext.getPackageManager().getProviderInfo(provider, GET_META_DATA); 2、androidx.startup 字符串 String startup = mContext.getString(R.string.androidx_startup); 3、获取组件信息中的 meta-data 数据 Bundle metadata = providerInfo.metaData; 4、遍历 meta-data 数据 if (metadata != null) { Set clazz = Class.forName(key); 4.2 检查指定的类是 Initializer 接口的实现类 if (Initializer.class.isAssignableFrom(clazz)) { Class> component = (Class>) clazz; 4.3 将 Class 添加到 mDiscovered Set 中 mDiscovered.add(component); 4.4 初始化此组件 doInitialize(component, initializing); } } } } } -> 4.3 mDiscovered 用于判断组件是否已经自动启动 public boolean isEagerlyInitialized(@NonNull Class> component) { return mDiscovered.contains(component); }上面的代码已经非常简化了,主要关注以下几点: 1、获取androidx.startup.InitializationProvider组件信息(在各个 Module 中声明的组件信息,会在manifest merger tool的处理下合并);2、androidx.startup字符串3、获取组件信息中的 meta-data 数据4、遍历 meta-data 数据 4.1 判断 meta-data 数据中,value 为 androidx.startup 的键值对4.2 检查指定的类是 Initializer 接口的实现类4.3 将 Class 添加到 mDiscovered Set 中,这将用于后续 判断组件是否已经自动启动4.4 初始化此组件AppInitializer.java private static final Object sLock = new Object(); 缓存每个组件的初始化结果 final Map initializer = (Initializer) instance; 3.1.3 遍历所依赖的组件 List |
CopyRight 2018-2019 实验室设备网 版权所有 |