官网项目Jetpack Startup库学习
作者:kandra777 发布时间:2021-10-03 16:33:21
简单认识一下Startup
nowinandroid项目作为目前google官方来演示MAD(现代Android开发技术)的示例项目,里面大量依赖运用了jetpack包下的各种库。通过分析学习这些库在项中的实际使用可以帮助我们比直接阅读库的文档来更好的理解和学习。希望通过学习后可以帮助到我们能熟练地在我们自己的项目中正确高效的使用到jetpack里面的各种强大库。不废话了,下面进入我们今天的正题——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" rel="external nofollow" >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
类,实现手动初始化完成。
来源:https://juejin.cn/post/7195036376650711097
猜你喜欢
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成
- 本文实例为大家分享了Android自定义双向滑动控件的具体代码,供大家参考,具体内容如下先看一下效果图1.SeekBarPressure工具
- 因为这段时间在学习Socket,所以就试着写了一个简单的聊天室。主要分为服务器端和多个客户端。利用服务器端作数据中转站,实现消息群发。1、服
- LinkedBlockingDeque介绍LinkedBlockingDeque是双向链表实现的双向并发阻塞队列。该阻塞队列同时支持FIFO
- 前言目前正在做的项目,为了增加用户的体验度,准备增加一些动画效果,其中底部栏中间按钮的点击事件参考了闲鱼的动效,便在此基础上仿写了该动效,并
- Java类加载器1、BootClassLoader: 用于加载Android Framework层class文件。2、PathClassLo
- 首先是获取特定进程对象,可以使用Process.GetProcesses()方法来获取系统中运行的所有进程,或者使用Process.GetC
- 首先我们看看为什么添加Watch。ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建
- springboot aop里的@Pointcut()的配置@Pointcut("execution(public * com.w
- IDEA 报错:无效的源发行版问题描述从SVN拉项目代码到本地后用idea运行,发现几个报错,关键的一个是:无效的源发行版,考虑是JDK版本
- 1.后台参数校验Spring Validation验证框架对参数的验证机制提供了@Validated(Spring JSR-303规范,是标
- 本文实例为大家分享了winform可拖动的自定义Label控件,供大家参考,具体内容如下效果预览:实现步骤如下:(1)首先在项目上右击选择:
- 在程序设计中,进行异常处理是非常关键和重要的一部分。一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度。试想一下
- 1.我做的是一个动态表格,就是在输入框里每输入一次数据并点击“添加”按钮,表格中就会新增一行记录。<table id="st
- 一般java在执行CMD命令时,通常是使用Runtime.getRuntime.exec(command)来执行的,这个方法有两种细节要注意
- Menustrip控件是一个菜单栏控件,可以加载菜单栏,在很多系统中都有用到。本文介绍下该控件的一些属性的常用方式。在页面FormMain_
- Springboot导出文件,前端下载文件后端代码可以把请求设置为post,我这里是Get @RequestMapping(value =
- 一、解决方案1声明:jdk1.8已经经过线上环境使用1. 调研JDK8的加密策略存在限制版本和无限制版本,随着越来越多的第三方工具只支持 J
- 前言所谓的字符串其实就是一串连续的字符,它是由许多单个字符连接而成的。如多个英文字母所组成的一个英文单词。字符串中可以包含任意字符,这些字符
- 查了网上的资料,有比较全面的,但有一个问题就是容易出现一个文字和框子不符合的现象。(仔细看,蓝色字母和背景的灰色有空白)要消除这个空白,很简