当前位置: 首页 > news >正文

Android Jetpack 系列(七)App Startup 启动优化

1. 简介

应用启动阶段的性能至关重要。许多第三方 SDK 或库都需要在应用启动时完成初始化,而常见做法通常有两种:

传统方式一: 在 Application 的 onCreate() 中初始化

这种方式虽然直观,但存在几个问题:

       问题 1:所有初始化逻辑都堆在 onCreate() 中,难以维护;

       问题 2:如果库开发者也需要自动初始化,就必须依赖宿主应用的改动;

       问题 3:对库作者来说,无法保证宿主是否正确初始化。

传统方式二: 通过 ContentProvider 自动初始化

为了让库能“自动”初始化,许多 SDK(如 WorkManager、Room、Firebase 等)会在自己的 AndroidManifest.xml 中声明一个 ContentProvider。
系统会在 Application.onCreate() 之前自动创建所有 Provider,这样库便能在应用启动前完成初始化。

但这种方式也存在问题:

    问题 1:冷启动开销大,每个库一个 Provider,系统会在启动时反射并创建多个对象,增加启动时间。

    问题 2:初始化顺序不可控,Android 并不保证 Provider 的执行顺序,若库之间存在依赖关系,容易出现初始化错误。

为此,Jetpack 推出了 App Startup,专门用于解决以上问题。App Startup 的优势:

  1. 简单配置即可实现自动初始化;
  2. 所有初始化逻辑共用一个 Provider,仅加载一次入口,性能更佳;
  3. 通过 dependencies() 显式声明依赖关系,保证顺序;
  4. 对应用开发者与库开发者都极为友好:
  • 应用开发者可借此简化 Application 逻辑;
  • 库开发者可实现“自动初始化”,无需宿主修改。

2. 添加依赖

要在项目中使用 App Startup,需要在模块的 build.gradle.kts 或 build.gradle 文件中添加如下依赖项:

dependencies {implementation("androidx.startup:startup-runtime:1.2.0")
}

3. 实现初始化组件

3.1. 实现 Initializer 接口

App Startup 的核心思想很简单,每个需要初始化的组件都对应一个 Initializer 类。实现 Initializer<T> 接口后,App Startup 就能在启动时自动调用它的 create() 方法完成初始化。

interface Initializer<T> {fun create(context: Context): Tfun dependencies(): List<Class<out Initializer<*>>>
}

方法说明:

  1. create():定义该组件的初始化逻辑。
  2. dependencies():声明依赖的其它组件初始化器,控制执行顺序。

我们在前面文章《Android Jetpack 系列(六)WorkManager 任务调度》中的【4.9.1. 默认自动初始化】中便介绍过 WorkManager 库能自动初始化正是因为它实现了这个接口,其源码如下:

public final class WorkManagerInitializer implements Initializer<WorkManager> {private static final String TAG = Logger.tagWithPrefix("WrkMgrInitializer");@NonNull@Overridepublic WorkManager create(@NonNull Context context) {// Initialize WorkManager with the default configuration.Logger.get().debug(TAG, "Initializing WorkManager with default configuration.");WorkManager.initialize(context, new Configuration.Builder().build());return WorkManager.getInstance(context);}@NonNull@Overridepublic List<Class<? extends androidx.startup.Initializer<?>>> dependencies() {return Collections.emptyList();}
}

3.2. 在 Manifest 中配置初始化器

App Startup 实际上是通过一个特殊的 ContentProvider 来发现并执行这些初始化器。该 Provider 名为:

androidx.startup.InitializationProvider

要启用自动初始化,只需在 AndroidManifest.xml 中添加 <meta-data> 配置。例如 WorkManager 的配置如下:

<application><providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:node="merge" ><meta-dataandroid:name="androidx.work.WorkManagerInitializer"android:value="androidx.startup" /></provider>......
</application>

说明:

  1. tools:node="merge" 用于多模块 Manifest 合并。
  2. android:name:配置组件初始化类的完整名称。
  3. android:value:固定为 "androidx.startup" 字符串。

3.3. 声明依赖关系

假设现在有两个库:Sdk1Sdk2,其中 Sdk2 依赖 Sdk1。可按如下方式定义:

Sdk1Initializer:

class Sdk1Initializer : Initializer<Sdk1Manager> {override fun create(context: Context): Sdk1Manager {Sdk1Manager.initialize(context)return Sdk1Manager.getInstance()}override fun dependencies(): List<Class<out Initializer<*>?>?> {return Collections.emptyList()}
}

Sdk2Initializer:

class Sdk2Initializer : Initializer<Sdk2Manager> {override fun create(context: Context): Sdk2Manager {Sdk2Manager.initialize(context)return Sdk2Manager.getInstance()}override fun dependencies(): List<Class<out Initializer<*>?>?> {val dependencies: MutableList<Class<out Initializer<*>?>?> = ArrayList()dependencies.add(Sdk1Initializer::class.java)return dependencies}
}

Manifest 配置:

<application><providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:node="merge"><meta-dataandroid:name="com.zyx.app.startup.Sdk2Initializer"android:value="androidx.startup" /></provider>......
</application>

说明:

  1. Sdk2Initializer 的 dependencies() 已声明了依赖关系,App Startup 会自动识别执行顺序(先 Sdk1 再 Sdk2)。
  2. 即使 Sdk1Initializer 未出现在任何 <meta-data> 中,也会被自动加载。
  3. 若两者都配置了 <meta-data>,不会重复初始化,因为 App Startup 内部有缓存与拓扑排序机制,能确保每个组件只执行一次。

4. 取消组件自动初始化

某些场景下,我们可能不希望在应用启动时立即初始化所有组件。

例如,有些 SDK 在初始化时会访问敏感数据或申请权限,通常应在用户同意隐私政策后再执行。

此时可以禁用自动初始化并改为手动初始化。

4.1 禁用单个组件

可通过移除该组件的 <meta-data> 项来禁用自动初始化,例如:

<application><providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:node="merge"><meta-dataandroid:name="com.zyx.app.startup.Sdk2Initializer"tools:node="remove" /></provider>......
</application>

若想禁用所有组件的自动初始化,可移除整个 Provider:

<application><providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:node="remove"></provider>......
</application>

说明:

  1. tools:node="remove" 会在 Manifest 合并阶段移除对应节点。
  2. 禁用组件自动初始化后,系统不会再递归初始化其依赖。

4.2. 手动初始化组件

在需要时,可使用以下方式手动触发初始化:

AppInitializer.getInstance(context).initializeComponent(Sdk2Initializer::class.java)

此调用会自动递归初始化其依赖(例如 Sdk1),无需手动顺序控制。

5. Lint 检查

App Startup 提供了内置的 Lint 规则,可帮助检测初始化配置是否正确:

./gradlew :app:lintDebug

Lint 会检测并提示以下问题:

  1. 未注册的初始化器;
  2. 依赖循环;
  3. 无效的 <meta-data>;
  4. 未使用的初始化器。

6. 总结

App Startup 为 Android 提供了一种统一、简洁且高效的组件初始化方案。

它不仅减少了启动阶段的性能开销,还让依赖关系更清晰、初始化逻辑更可控。

无论是应用开发者还是 SDK 作者,都能从中获益。

更多详细的 App Startup 介绍,请访问 Android 开发者官网

http://www.dtcms.com/a/479785.html

相关文章:

  • 网站建设的收费网站建设优化开发公司
  • 【代码收藏夹·Python】使用paho连接MQTT
  • 怎么把网站排名优化秦皇岛网站建设
  • 百度推广登录平台登录泊头 网站优化
  • JS - 数据类型
  • 站长之家新网址网络营销外包有限公司
  • 未来之窗昭和仙君(十六)网页数字动画函数——东方仙盟筑基期
  • 新手怎么学习网站建设网站建设横幅
  • 怎样做简单公司网站ip代理提取网站源码
  • 【Python】从 MP4 文件中提取中英双语字幕并生成双语字幕文件(如 .srt)
  • 基于ffmpeg库,在AGX上编译jetsonFFmpeg库带有硬件加速的h264_nvmpi视频编解码器
  • wordpress熊掌号自动提交seo如何使用wordpress优化
  • 网站维护费一般多少钱湖南好搜网站建设
  • 机器人软件开发和网站开发wordpress后台登录
  • 3d演示中国空间站建造历程牡丹江建站
  • 服务器网站管理系统泰山信息科技有限公司
  • 网站备案是域名备案还是服务器备案长沙房价一览表
  • 行业网站名称广州公司网站托管
  • wordpress站点地址写错网页设计师考试报名
  • 保定涿州网站建设网站开发人员的工作
  • [Qlib] 数据处理`DataHandlerLP` | `Alpha158`
  • wordpress批量拿站263企业邮箱腾讯登录入口
  • 网站图片设置方法在网站上做远程教育系统多少钱
  • 深度学习(三)
  • 珠海本地网站设计公司做网站售后好的公司
  • 门户网站宣传方案做一个网站如何赚钱
  • 网站开发设计流程文档广告网页推广方案
  • 网站维护模式移动网站适配
  • 营销网站建设的目的北京百度总部电话
  • C++STL---静态数组array