Jetpack ---- WorkManager入门(三)

翻译自android官网,可直接去官网观看

Jetpack ---- WorkManager入门(三)

  • 四、先进概念
    • (一)自定义WorkManager配置和初始化
      • 按需初始化
        • 删除默认的初始化程序
        • Implement Configuration.Provider
      • WorkManager 2.1.0之前的自定义初始化
        • 默认初始化
        • 自定义初始化
    • (二)WorkManager中的线程
      • 总览
      • Threading in Worker
      • Threading in CoroutineWorker
      • Threading in RxWorker
      • Threading in ListenableWorker
    • (三)支持长期工作的 workers
      • 创建和管理长期工作的workers
        • Java
        • Kotlin
      • 将foreground service类型添加到长时间运行的worker
        • 在app manifest中声明foreground service类型
        • 在运行时指定foreground service类型
  • 五、从Firebase JobDispatcher迁移到WorkManager
    • Gradle 设置
    • 从 JobService 到 workers
      • JobService 映射到 ListenableWorker
      • SimpleJobService 映射到 Worker
    • JobBuilder 映射到 WorkRequest
      • 设置Worker的输入
      • 设置Worker的限制条件
      • 创建 WorkRequest(一次性或定期)
    • 调度工作
    • 取消work
    • 初始化 WorkManager
  • 六、从 GCMNetworkManager 迁移到 WorkManager
    • 迁移到 WorkManager
      • 包含 WorkManager 库
      • 修改清单
      • 定义Worker
      • 调度工作请求
    • API 映射
      • 限制条件映射
      • 其他映射
        • Tags
        • Task parameters

四、先进概念

(一)自定义WorkManager配置和初始化

默认情况下,WorkManager在应用程序启动时自动配置自己,使用适用于大多数应用程序的合理选项。如果需要对WorkManager管理和计划工作方式进行更多控制,可以通过自己初始化WorkManager来自定义WorkManager配置。

为WorkManager提供自定义初始化的最灵活的方法是使用WorkManager 2.1.0及更高版本中提供的按需初始化。其他选项将在后面讨论。

按需初始化

按需初始化允许您仅在需要该组件时创建WorkManager,而不是每次启动应用程序时创建该组件。这样做会使WorkManager脱离关键的启动路径,从而提高应用程序启动性能。使用按需初始化:

删除默认的初始化程序

要提供自己的配置,必须首先删除默认的初始化程序。为此,请使用tools:node="remove"合并规则对AndroidManifest.xml 进行更新 :

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />

要了解有关在清单中使用合并规则的更多信息,请参阅有关 合并多个清单文件的文档。

Implement Configuration.Provider

让您的Application类实现该 Configuration.Provider 接口,并提供您自己的Configuration.Provider.getWorkManagerConfiguration()实现 。当您需要使用WorkManager时,请确保调用方法 WorkManager.getInstance(Context)。WorkManager调用您的应用程序的自定义getWorkManagerConfiguration()方法以发现其Configuration。(您无需调用 WorkManager.initialize()来初始化自己。)

注意:如果WorkManager.getInstance()在WorkManager初始化之前调用不推荐使用的无参数方法,则该方法将引发异常即使不自定义WorkManager,也应始终使用WorkManager.getInstance(Context)该方法

这是自定义getWorkManagerConfiguration()实现的示例:

class MyApplication extends Application implements Configuration.Provider {
   
    @Override
    public Configuration getWorkManagerConfiguration() {
   
        return Configuration.Builder()
                .setMinimumLoggingLevel(android.util.Log.INFO)
                .build();
    }
}

WorkManager 2.1.0之前的自定义初始化

对于版本2.1.0之前的WorkManager版本,有两个初始化选项。在大多数情况下, 您只需要默认的初始化即可。为了更精确地控制WorkManager,您可以 指定自己的配置。

默认初始化

应用程序启动时,WorkManager使用自定义ContentProvider进行初始化。此代码位于内部类androidx.work.impl.WorkManagerInitializer中, 并使用default Configuration。除非您明确禁用它,否则将自动使用默认的初始化程序 。默认的初始化程序适用于大多数应用程序。

自定义初始化

如果要控制初始化过程,则必须 禁用默认的初始化程序,然后定义自己的自定义配置。

删除默认的初始化程序后,您可以手动初始化WorkManager:

// provide custom configuration
Configuration myConfig = new Configuration.Builder()
    .setMinimumLoggingLevel(android.util.Log.INFO)
    .build();

//initialize WorkManager
WorkManager.initialize(this, myConfig);

确保WorkManager 单例的初始化在Application.onCreate() 中或ContentProvider.onCreate()中运行

有关可用的自定义的完整列表,请参见 Configuration.Builder() 参考文档。

(二)WorkManager中的线程

总览

在WorkManager入门中,我们提到WorkManager代表您异步执行后台工作。基本实现可满足大多数应用程序的需求。对于更高级的用例,例如正确处理正在停止的工作,您应该了解WorkManager中的线程和并发性。

WorkManager提供了四种不同类型的工作原语:

  • Worker是最简单的实现,也是您在上一节中看到的实现。WorkManager会在后台线程上自动运行它(您可以重写)。在Threading in Worker中阅读有关Worker实例线程的更多信息。
  • CoroutineWorker是Kotlin用户的推荐实施。CoroutineWorker实例公开了用于后台工作的暂停功能。默认情况下,它们运行default Dispatcher,您可以对其进行自定义。在 Threading in CoroutineWorker阅读更多关于CoroutineWorker实例中线程的信息。。
  • RxWorker是RxJava用户的推荐实现。如果许多现有的异步代码都在RxJava中建模,则应使用RxWorkers。与所有RxJava概念一样,您可以自由选择所需的线程策略。在RxWorker的Threading中了解有关RxWorker实例中的线程的更多信息。
  • ListenableWorker为Worker,CoroutineWorker和RxWorker的基类。它适用于必须与基于回调的异步API(例如,FusedLocationProviderClient并且不使用RxJava)进行交互的Java开发人员。在Threading in ListenableWorker中阅读有关ListenableWorker实例中线程化的更多信息。

Threading in Worker

使用Worker时,WorkManager会自动在后台线程上调用Worker.doWork() 。后台线程来自WorkManager Configuration中指定的线程Executor 。默认情况下,WorkManager会为您设置一个Executor,但您也可以自定义自己的。例如,您可以在应用程序中共享一个现有的后台执行器,创建一个单线程Executor以确保您的所有后台工作都按顺序执行,甚至可以指定一个custom Executor。要自定义 Executor,请确保手动初始化WorkManager

手动配置WorkManager时,可以指定Executor以下内容:

WorkManager.initialize(
    context,
    new Configuration.Builder()
        .setExecutor(Executors.newFixedThreadPool(8))
        .build());

这是一个简单Worker示例,可将网页内容下载100次:

public class DownloadWorker extends Worker {
   

    public DownloadWorker(Context context, WorkerParameters params) {
   
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
   
        for (int i = 0; i < 100; i++) {
   
            try {
   
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
   
                return Result.failure();
            }
        }

        return Result.success();
    }

}

请注意,Worker.doWork()这是一个同步调用-您应该以阻塞的方式完成整个后台工作,并在方法退出时完成它。如果您在异步API中调用doWork()并返回Result,则您的回调可能无法正常运行。如果您遇到这种情况,请考虑使用ListenableWorker(请参见ListenableWorker中的Threading)。

当一个正在运行的Worker以任何理由停止,它接收到Worker.onStopped()回调。重写此方法或调用Worker.isStopped() 检查点代码,并在必要时释放资源。当Worker 在上面的例子中停止时,它可能会在其下载项目的循环的中间,并将继续这样做,即使它已停止。要优化此行为,可以执行以下操作:

public class DownloadWorker extends Worker {
   

    public DownloadWorker(Context context, WorkerParameters params) {
   
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
   
        for (int i = 0; i < 100; ++i) {
   
            if (isStopped()) {
   
                break;
            }

            try {
   
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
   
                return Result.failure();
            }
        }

        return Result.success();
    }
}

一旦Worker停止,Worker.doWork()返回的内容就无关紧要 ;Result将被忽略

Threading in CoroutineWorker

对于Kotlin用户,WorkManager为协程提供了一流的支持。首先,在gradle文件中添加work-runtime-ktx。您应该扩展CoroutineWorker而不是扩展Worker,它具有doWork()的暂停版本。例如,如果要构建一个简单的程序CoroutineWorker 来执行某些网络操作,则可以执行以下操作:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
   

    override suspend fun doWork(): Result = {
   
        val data = downloadSynchronously("https://www.google.com")
        saveData(data)

        Result.success()
    }
}

请注意,这CoroutineWorker.doWork()是一个暂停功能。不像Worker,这个代码并不能对运行在您Configuration指定的Executor。而是默认为Dispatchers.Default。您可以通过提供自己的CoroutineContext进行自定义。在上面的示例中,您可能希望对Dispatchers.IO进行以下操作:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
   

    override suspend fun doWork(): Result {
   
        withContext(Dispatchers.IO) {
   
            val data = downloadSynchronously("https://www.google.com")
            saveData(data)
            return Result.success()
        }

    }
}

CoroutineWorker通过取消协程并传播取消信号来自动处理停工。您不需要做任何特殊的事情来处理停工。

Threading in RxWorker

我们提供WorkManager和RxJava之间的互操作性。首先,除了gradle文件中的work-runtime之外,还包括work-rxjava3依赖项。还有一个work-rxjava2依赖项支持rxjava2。

然后,应该扩展RxWorker而不是扩展Worker。最终覆盖RxWorker.createWork()方法返回指示执行结果的Single,如下所示:

public class RxDownloadWorker extends RxWorker {
   

    public RxDownloadWorker(Context context, WorkerParameters params) {
   
        super(context, params);
    }

    @NonNull
    @Override
    public Single<Result> createWork() {
   
        return Observable.range(0, 

你可能感兴趣的:(android)