通过这篇文章你将学习到以下内容:
App Startup 是什么?
App Startup 为我们解决了什么问题?
为什么无论是 Google 还是第三方库,初始化时都会在 ContentProvider 里面进行初始化?
在 ContentProvider 里初始化会带来什么性能问题?
ContentProvider 启动顺序源码分析?
如何正确使用 App Startup?
自动初始化。
手动初始化(也是延迟初始化)。
1.App Startup 是什么?
来自 Google 文档:App Startup 是 Android Jetpack 最新成员,提供了在 App 启动时初始化组件简单、高效的方法,无论是 library 开发人员还是 App 开发人员都可以使用 App Startup 显示的设置初始化顺序。
简单的说就是 App Startup 提供了一个 ContentProvider 来运行所有依赖项的初始化,避免每个第三方库单独使用 ContentProvider 进行初始化,从而提高了应用的程序的启动速度。
上图表示现在我们有三个库分别 LibraryA、LibraryB、和 LibraryC 它们使用自己的 ContentProviders 进行初始化。 而 App Startup 提供了一个 ContentProvider 来运行所有依赖项的初始化(LibraryA、LibraryB、和 LibraryC),如下图所示。 image.png
2.AndroidX App Startup 为我们解决了什么问题?
刚才我们说到无论是 Google 提供的库还是第三方库,App 启动运行时会初始化一些逻辑,它们为了方便开发者使用,避免开发者手动调用,使用 ContentProvider 进行初始化,例如 WorkManager 在应用启动时使用 ContentProvider 进行初始化,我们来看一下 WorkManager 的源码,先来看一下 AndroidManifest.xml 文件内容。
image.png
如上所见,我们可以看到在 AndroidManifest.xml 文件内定义了一个名为 WorkManagerInitializer 的 ContentProvider,我来看看 WorkManagerInitializer 里面都做了什么。
image.png
如上所见其实就是在 WorkManagerInitializer 的 onCreate() 方法里面,使用默认配置初始化 WorkManager。
我们也来模仿 WorkManager 写一个 Demo,这里只贴出部分代码,更多信息查看 GitHub 上的 AppStartupSimple下面的 ContentProvider 模块。
在 AndroidManifest.xml 文件中注册 WorkContentProvider。
image.png
运行 App 日志如下所示。 image.png
假设你的 App 有很多类似于 WorkManager 这样的库,都在 ContentProvider 里面进行一些初始化工作,在 App 启动时运行多个 ContentProvider,这样会带来一些问题:
多个 ContentProvider 会增加了 App 启动运行的时间。
ContentProvider 的 onCreate 方法会先于 Application 的 OnCreate 方法执行,这是在冷启动阶段自动运行初始化的,来看一下 Android 10 系统源码。 image.png
这是在 App 冷启动时自动运行初始化的,这样只会增加 App 的加载时间,用户希望 App 加载得快,启动慢会带来糟糕的用户体验,AndroidX App Startup 正是为了解决这个问题而出现的。
3.如何正确使用 AndroidX App Startup?
使用 AndroidX App Startup 来运行所有依赖项的初始化有两种方式:
自动初始化。
手动初始化(也是延迟初始化)。
具体可以查看 GitHub 上的 AppStartupSimple 下面的 Startup-Library 模块相关代码。
自动初始化
实现 Initializer 接口,并重写两个方法,来初始化组件。 image.png
create(Context): 这里进行组件初始化工作。
dependencies(): 返回需要初始化的列表,同时设置 App 启动时依赖库运行的顺序,假设 LibaryC 依赖于 LibaryB,LibaryB 依赖于 LibaryA,App 启动运行时,会先运行 LibaryA 然后运行 LibaryB 最后运行 LibaryC。
在 AndroidManifest.xml 文件中注册 InitializationProvider。 image.png
App 启动的时 App Startup 会读取 AndroidManifest.xml 文件里面的 InitializationProvider 下面的 <meta-data> 声明要初始化的组件,完成自动初始化工作。
手动初始化(也是延迟初始化)
在 build.gradle 文件内添加依赖,和上文一样。
创建一个类 LibaryD 实现 Initializer 接口,并重写两个方法,来初始化组件,和上文一样。
只需要在 <meta-data> 标签内添加 tools:node="remove" 清单合并工具会将它从清单文件中删除。 在需要的地方进行初始化,调用以下代码进行初始化。 image.png
如果组件初始化之后,再次调用 AppInitializer.initializeComponent() 方法不会再次初始化。
手动初始化(也是延迟初始化)是非常有用的,组件不需要在 App 启动时运行,只需要在需要它地方运行,可以减少 App 的启动时间,提高启动速度。
总结
这篇文章主要介绍了以下内容:
ContentProvider 启动顺序源码分析。
App Startup 是 Jetpack 的新成员,是为了解决因 App 启动时运行多个 ContentProvider 会增加 App 的启动时间的问题。
使用了一个 InitializationProvider 管理多个依赖项,消除了每个库单独使用 ContentProvider 成本,减少初始化时间。
App Startup 允许你自定义组件初始化顺序。
App Startup 可以自动初始化 AndroidManifest.xml 文件中 InitializationProvider 下面的 <meta-data> 声明要初始化的组件。
App Startup 提供了一种延迟初始化组件的方法,减少 App 初始化时间。
了解更多干货内容可以添加我的q峮 1080621881 。
网友评论