nowinandroid项目作为目前google官方来演示MAD(现代Android开发技术)的示例项目,里面大量依赖运用了jetpack包下的各种库。通过分析学习这些库在项中的实际使用可以帮助我们比直接阅读库的文档来更好的理解和学习。希望通过学习后可以帮助到我们能熟练地在我们自己的项目中正确高效的使用到jetpack里面的各种强大库。不废话了,下面进入我们今天的正题——Startup
简单认识一下Startup
App Startup | Android Developers 官网的指南有兴趣可以看看
我们今天不讲原理,你只需知道这个库比之前用多个content provider去实现初始化更高效,更精确,更显性,也就是说能合并content provider提升app的启动速度,能准确的控制初始化顺序,能清晰的从代码知道依赖关系。仅仅这些可能jym会说,我们项目不在乎那点启动速度的提升,也没有很多三方库需要走初始化等,根本用不到这个库。是的,我之前也是这么理解的,但是通过nowinandroid项目发现,有些jetpack内的其他库的初始化现在也交给Startup来完成了,这一点就很重要了。意味着我们可以少写很多样板代码,少写也意味着少犯错。所以我觉的还是有必要单独写一篇文章来说说Startup
编写初始化的代码步骤很简单主要就分3步:
- 定义实现
Initializer
接口的实现类 - 配置manifest
- 自动或手动调用初始化操作
OK了!就这简单3步,下面我们结合项目例子来看
项目代码
- 先看第一步
object Sync {
// This method is a workaround to manually initialize the sync process instead of relying on
// automatic initialization with Androidx Startup. It is called from the app module's
// Application.onCreate() and should be only done once.
fun initialize(context: Context) {
AppInitializer.getInstance(context)
.initializeComponent(SyncInitializer::class.java)
}
}
internal const val SyncWorkName = "SyncWorkName"
/**
* Registers work to sync the data layer periodically on app startup.
*/
class SyncInitializer : Initializer<Sync> {
override fun create(context: Context): Sync {
WorkManager.getInstance(context).apply {
// Run sync on app startup and ensure only one sync worker runs at any time
enqueueUniqueWork(
SyncWorkName,
ExistingWorkPolicy.KEEP,
SyncWorker.startUpSyncWork(),
)
}
return Sync
}
override fun dependencies(): List<Class<out Initializer<*>>> =
listOf(WorkManagerInitializer::class.java)
}
定一个SyncInitializer
类实现了泛型为Sync
的Initializer
接口。需要重写接口定义的两个方法:
-
create()
方法, 它包含初始化组件所需的所有操作,并返回一个Sync
的实例. -
dependencies()
方法, 返回当前初始化器需要依赖的其他初始化器集合,我们可以用这个方法来变相的实现各个初始化器的执行顺序。
所以在create
方法里面的执行WorkManager.getInstance(context)
方法是安全的。我们这篇只关注Startup所以我们只用知道在这个地方WorkManager做了些事情就行,后面会另开一篇单独讲WorkManager。为啥是安全的呢?因为在dependencies
方法里面先执行了WorkManagerInitializer::class.java
初始化。我们再来看看这个类。
public final class WorkManagerInitializer implements Initializer<WorkManager> {
private static final String TAG = Logger.tagWithPrefix("WrkMgrInitializer");
@NonNull
@Override
public WorkManager create(@NonNull Context context) {
// Initialize WorkManager with the default configuration.
Logger.get().debug(TAG, "Initializing WorkManager with default configuration.");
//这个地方已经完成了单例的构建,后面再调用WorkManager.getInstance(context)获取实例,否则报错
WorkManager.initialize(context, new Configuration.Builder().build());
return WorkManager.getInstance(context);
}
@NonNull
@Override
public List<Class<? extends androidx.startup.Initializer<?>>> dependencies() {
//这里WorkManager的初始化不需要其他初始化构造器,所以返回的是个空集合
return Collections.emptyList();
}
}
以上我们就把第一步走完了,现在再来看第二步
- 再看第二步
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- TODO: b/2173216 Disable auto sync startup till it works well with instrumented tests -->
<meta-data
android:name="com.google.samples.apps.nowinandroid.sync.initializers.SyncInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
</application>
</manifest>
这里需要注意的是tools:node="remove"
,在provider层级用的话是全局取消自动初始化,在meta-data层级用的话是单个组件取消自动初始化。例子展示的是单个组件取消自动初始化。另外注意的一点是被依赖的初始化组件是不需要再另外在manifest里面声明的,这就是为什么WorkManagerInitializer
没有声明。
- 最后一步
@HiltAndroidApp
class NiaApplication : Application(), ImageLoaderFactory {
override fun onCreate() {
super.onCreate()
// Initialize Sync; the system responsible for keeping data in the app up to date.
Sync.initialize(context = this)
}
/**
* Since we're displaying SVGs in the app, Coil needs an ImageLoader which supports this
* format. During Coil's initialization it will call `applicationContext.newImageLoader()` to
* obtain an ImageLoader.
*
* @see <a href="https://github.com/coil-kt/coil/blob/main/coil-singleton/src/main/java/coil/Coil.kt">Coil</a>
*/
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.components {
add(SvgDecoder.Factory())
}
.build()
}
}
上面的代码是app的Application,我们今天的重点是Startup,所以我们先不管其他的。只用看onCreate
下的Sync.initialize(context = this)
方法。
object Sync {
// This method is a workaround to manually initialize the sync process instead of relying on
// automatic initialization with Androidx Startup. It is called from the app module's
// Application.onCreate() and should be only done once.
fun initialize(context: Context) {
AppInitializer.getInstance(context)
.initializeComponent(SyncInitializer::class.java)
}
}
AppInitializer.getInstance(context).initializeComponent(SyncInitializer::class.java)
传入SyncInitializer
类,实现手动初始化完成。
以上就是nowinandroid项目对Startup库的使用,并且上面我们也知道了我们自定义的初始化器在初始化的时候通过WorkManager做了些事情。那么下篇我们还是通过这个例子来看看nowinandroid是怎么使用WorkManager这个库的。
水平有限,写作不易。各位jym高抬贵手点个赞留个言都是对我最大的鼓励
作者:kandra777
链接:https://juejin.cn/post/7195036376650711097
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型 2、注解深入浅出 3、发编程 4、数据传输与序列化 5、Java虚拟机原理 6、高效IO ……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析 2.Okhttp3源码解析 3.ButterKnife源码解析 4.MPAndroidChart 源码解析 5.Glide源码解析 6.Leakcanary 源码解析 7.Universal-lmage-Loader源码解析 8.EventBus 3.0源码解析 9.zxing源码分析 10.Picasso源码解析 11.LottieAndroid使用详解及源码解析 12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
腾讯Bugly:对字符串匹配算法的一点理解
爱奇艺:安卓APP崩溃捕获方案——xCrash
字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
百度APP技术:Android H5首屏优化实践
支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
携程:从智行 Android 项目看组件化架构实践
网易新闻构建优化:如何让你的构建速度“势如闪电”?
…
四、高级kotlin强化实战
1、Kotlin入门教程 2、Kotlin 实战避坑指南 3、项目实战《Kotlin Jetpack 实战》
从一个膜拜大神的 Demo 开始
Kotlin 写 Gradle 脚本是一种什么体验?
Kotlin 编程的三重境界
Kotlin 高阶函数
Kotlin 泛型
Kotlin 扩展
Kotlin 委托
协程“不为人知”的调试技巧
图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用 2.Android之PullToRefresh控件源码解析 3.Android-PullToRefresh下拉刷新库基本用法 4.LoadSir-高效易用的加载反馈页管理框架 5.Android通用LoadingView加载框架详解 6.MPAndroidChart实现LineChart(折线图) 7.hellocharts-android使用指南 8.SmartTable使用指南 9.开源项目android-uitableview介绍 10.ExcelPanel 使用指南 11.Android开源项目SlidingMenu深切解析 12.MaterialDrawer使用指南六、NDK模块开发
1、NDK 模块开发 2、JNI 模块 3、Native 开发工具 4、Linux 编程 5、底层图片处理 6、音视频开发 7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述 2、Windows中Flutter开发环境搭建 3、编写你的第一个Flutter APP 4、Flutter开发环境搭建和调试 5、Dart语法篇之基础语法(一) 6、Dart语法篇之集合的使用与源码解析(二) 7、Dart语法篇之集合操作符函数与源码分析(三) …
八、微信小程序开发
1、小程序概述及入门 2、小程序UI开发 3、API操作 4、购物商场项目实战……
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集