官网项目Jetpack Startup库学习

作者:kandra777 时间:2021-10-03 16:33:21 

简单认识一下Startup

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

官网项目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类实现了泛型为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" 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

标签:Jetpack,Startup,库
0
投稿

猜你喜欢

  • Java读取、写入文件如何解决乱码问题

    2023-08-26 11:16:00
  • C#如何实现dataGridView动态绑定数据

    2022-10-26 09:23:18
  • PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例

    2023-11-26 15:05:59
  • 简单了解Spring中常用工具类

    2021-09-24 10:44:28
  • c# 在windows中操作IIS设置FTP服务器的示例

    2023-07-18 06:13:01
  • Mybatis模糊查询之三种定义参数方法和聚合查询、主键回填实现方法

    2023-06-27 03:23:44
  • java生成jar包并且单进程运行的实例

    2021-08-30 00:40:55
  • SpringBoot切面拦截@PathVariable参数及抛出异常的全局处理方式

    2023-05-27 13:59:52
  • java实现鲜花销售系统

    2023-08-29 20:23:42
  • 关于@Scheduled不执行的原因分析

    2021-06-27 17:13:20
  • C#实现批量更改文件名称大小写或扩展名

    2023-03-25 02:20:50
  • C# Newtonsoft.Json 解析多嵌套json 进行反序列化的实例

    2022-04-09 11:23:13
  • SpringBoot 读取yml文件的多种方式汇总

    2023-08-03 13:10:43
  • 关于C# TabPage如何隐藏的问题

    2023-01-10 00:01:39
  • java中maven下载和安装步骤说明

    2022-03-05 23:07:59
  • Spring MVC结合Spring Data JPA实现按条件查询和分页

    2023-03-04 07:24:36
  • Spring占位符Placeholder的实现原理解析

    2023-03-14 18:14:00
  • android仿微信联系人索引列表功能

    2023-06-22 17:33:30
  • Spring实战之注入集合值操作示例

    2023-03-04 04:02:53
  • Android 文件数据存储实例详解

    2023-07-28 17:08:03
  • asp之家 软件编程 m.aspxhome.com