通过官网项目来学习——Jetpack之Startup库

nowinandroid项目作为目前google官方来演示MAD(现代Android开发技术)的示例项目,里面大量依赖运用了jetpack包下的各种库。通过分析学习这些库在项中的实际使用可以帮助我们比直接阅读库的文档来更好的理解和学习。希望通过学习后可以帮助到我们能熟练地在我们自己的项目中正确高效的使用到jetpack里面的各种强大库。不废话了,下面进入我们今天的正题——Startup

简单认识一下Startup

App Startup | Android Developers 官网的指南有兴趣可以看看

我们今天不讲原理,你只需知道这个库比之前用多个content provider去实现初始化更高效,更精确,更显性,也就是说能合并content provider提升app的启动速度,能准确的控制初始化顺序,能清晰的从代码知道依赖关系。仅仅这些可能jym会说,我们项目不在乎那点启动速度的提升,也没有很多三方库需要走初始化等,根本用不到这个库。是的,我之前也是这么理解的,但是通过nowinandroid项目发现,有些jetpack内的其他库的初始化现在也交给Startup来完成了,这一点就很重要了。意味着我们可以少写很多样板代码,少写也意味着少犯错。所以我觉的还是有必要单独写一篇文章来说说Startup

编写初始化的代码步骤很简单主要就分3步:

  1. 定义实现Initializer接口的实现类
  2. 配置manifest
  3. 自动或手动调用初始化操作

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类实现了泛型为SyncInitializer接口。需要重写接口定义的两个方法:

  • 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、购物商场项目实战……

全套视频资料:

一、面试合集

二、源码解析合集

三、开源框架合集

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容