Android JetPack App Startup 使用及源码浅析(一)

简介: Android JetPack App Startup 使用及源码浅析

前言


前一阵子,写了几篇 Android 启动优化的文章,主要是从两个方面论述的。

  1. Application 多线程异步加载,以及怎么解决多线程任务依赖的问题
  2. 首页布局优化,从常规的布局嵌套优化到渐进式加载,再到异步加载。


今天,就让我们来聊一聊 JetPack App Startup。


目录大概是这样的


1 什么是 JetPack App Startup 2 JetPack App Startup 能解决什么问题 3 JetPack App Startup 基本使用 4 JetPack App Startup 进阶使用 5 JetPack App Startup 源码浅析 6 小结


什么是 JetPack App Startup


我们先来看一下官方的解释,官方地址:developer.android.com/topic/libra…


The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.


Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.


翻译过来就是:


  1. App Startup 这个库提供了一个组件,可以在应用程序启动的时候初始化。
  2. 开发人员可以使用这个组件精简启动序列和显式地设置初始化的顺序。
  3. 我们不需要为每个组件定义单独的 ContentProvider,App Startup 允许您定义的所有组件化共享一个内容提供者。这样可以极大地减少高应用程序的启动时间


JetPack App Startup 能解决什么问题


听了上面的介绍,是不是还有点懵?


App Startup 能减少高应用程序的启动时间,它是怎么做到的?


做过 Android 启动优化的,可能都知道,Android 的启动流程是这样的。


f3d23378d160b9f1f28b91fb0cf3611e_62f0fc7a8a722c087ed0160123dc2b6a.png


从 Application#attachBaseContext 到 ContentProvider#onCreate,到 Application#onCreate 再到 MainActivity#onCreate。


而 App Startup 设计的初衷,正是为了收拢 ContentProvider。有不少第三方的 SDk,为了使用者不必手动调用 SDK#init 方法,使用了 ContentProvider 这一个骚操作。


在 AndroidManifest 里面注册了自己的 xxSDkProvider,然后在 xxSDkProvider 的 onCreate 方面里面进行初始化,确实调用者不需要自己初始化了,可却增加了启动耗时,如果要作优化,还得自己剔除 ContentProvider 的初始化,值不值得,我是感觉没必要,这操作是真的骚。


<application ...>
    <provider
        android:name=".xxSDkProvider"
        android:authorities="${applicationId}.xxSDkProvider"
        android:exported="false" />
</application>


class XXSDKProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        Log.d(TAG, "XXSDKProvider create()")
        XXSDK.init()
        return true
    }
    .....
}


同时,这里给做启动优化的同学提供了一种思路。打开你的 Apk,看一下 AndroidManiest 里面有多少 provider,看一下是否有这样的骚操作。如果有,改一下,说不定启动优化,一下子就减少了 100 多 毫秒。


接下来,我们来看一下 AppStartUp 怎么使用


AppStartUp 基本使用


简单来说,分为三步


  1. gradle 文件引入App Startup 库。
  2. 自定义一个用于初始化的 Initializer。
  3. 将自定义 Initializer 配置到 AndroidManifest.xml 当中。


第一步,在 build.gradle 文件添加依赖


dependencies {
    implementation "androidx.startup:startup-runtime:1.0.0"
}


第二步:自定义实现 Initializer 类


主要有两个方法


  1. T create(@NonNull Context context) 初始化一个组件,返回给 Application
  2. List<Class<? extends Initializer<?>>> dependencies() 当前的 Initializer 依赖于哪些 Initializers,通过这个可以确定先后启动的顺序


我们以官方的例子来讲解


// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
    override fun create(context: Context): WorkManager {
        val configuration = Configuration.Builder().build()
        WorkManager.initialize(context, configuration)
        return WorkManager.getInstance(context)
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // No dependencies on other libraries.
        return emptyList()
    }
}


WorkManagerInitializer 返回一个 WorkManager,它不需要依赖于其他的 Initializer,直接返回 emptyList() 即可。


如果需要依赖其他的 Initializer,重写 dependencies 方法,返回即可。如下面的 ExampleLoggerInitializer 依赖于 WorkManagerInitializer


// Initializes ExampleLogger.
class ExampleLoggerInitializer : Initializer<ExampleLogger> {
    override fun create(context: Context): ExampleLogger {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context))
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return listOf(WorkManagerInitializer::class.java)
    }
}
class  ExampleLogger(val workManager: WorkManager){
}


第三步:在 AndroidManifest 里面配置自定义的 InitializationProvider


<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <!-- This entry makes ExampleLoggerInitializer discoverable. -->
    <meta-data  android:name="com.xj.anchortask.appstartup.ExampleLoggerInitializer"
        android:value="androidx.startup" />
</provider>


它是有固定格式的,配置者只需要配置 meta-data 中的 name 即可。 android:name="com.xj.anchortask.appstartup.ExampleLoggerInitializer" 这里的 name 是我们自定义的 Initializer 全路径。


程序运行跑起来,可以看到以下输出结果,符合我们的预期


2021-04-17 17:48:42.049 28059-28059/com.xj.anchortask I/AnchorTaskApplication: attachBaseContext: 2021-04-17 17:48:42.077 28059-28059/com.xj.anchortask I/AnchorTaskApplication: create: WorkManagerInitializer init 2021-04-17 17:48:42.077 28059-28059/com.xj.anchortask I/AnchorTaskApplication: create: ExampleLoggerInitializer init 2021-04-17 17:48:42.084 28059-28059/com.xj.anchortask I/AnchorTaskApplication: onCreate:


相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
140 0
安卓项目:app注册/登录界面设计
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
123 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
1月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
44 6
|
2月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
162 2
|
2月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
103 3
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
69 10
|
1月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
224 0
|
2月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
1月前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
482 7
|
1月前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
534 1