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

敞开生长之旅!这是我参加「日新计划 2 月更文应战」的第 1 天,点击检查活动详情

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

简略认识一下Startup

通过官网项目来学习-Jetpack之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这个库的。

经过官网项目来学习-Jetpack之WorkManager库 – ()

敞开生长之旅!这是我参加「日新计划 2 月更文应战」的第 1 天,点击检查活动详情

水平有限,写作不易。各位jym高抬贵手点个赞留个言都是对我最大的鼓舞