IntentService 或 JobScheduler 在 onPause 期间执行 I/O 密集数据保存操作

IntentService or JobScheduler to perform I/O intensive data save operation during onPause

目前,在 Activity onPause() 期间,我正在执行 I/O 操作,以将应用程序数据持久保存到磁盘中。

private void save() {
    saveDataToFiles();
}

public void onPause() {
    super.onPause();
    save()
}

随着时间的推移,应用需求变得越来越复杂。不仅我需要将数据保存到文件中。我还需要执行几个额外的任务。

因此,代码将演变为

private void save() {
    saveDataToFiles();
    saveDataToSQLite();
    saveDataOverTheInternet();
}

public void onPause() {
    super.onPause();
    save()
}

现在,save() 方法是一个非常耗时的方法。在 UI 线程中执行耗时操作不是一个好主意。

我经历了 (它的日期是 2016 年。因此,一些建议可能不再有效。)

我最初的计划是 save() 方法由 IntentService

执行

我不打算使用 Service。正如您在 https://developer.android.com/guide/components/services.html 中看到的 2 Hello... 示例,具有自己的线程机制的 extends Serviceextends IntentService[=36= 复杂得多]

但是,我也注意到一些来自 Google https://developer.android.com/guide/components/bound-services.html

的警告

Note: If your app targets Android 5.0 (API level 21) or later, it's recommended that you use the JobScheduler to execute background services.

我的目标是 API 25。所以,我应该认真对待这个建议。

我的问题是

  1. 我应该在 onPause() 期间使用 JobScheduler 还是 IntentService?我估计 save() 的执行时间应该不会超过 10 秒。
  2. 我会遇到数据不一致的问题吗?我该如何克服?考虑以下情况
    • onPause 触发。启动一个线程执行save
    • onResume 触发。 Loader 启动,执行 load
    • 因为 onPause 的前一个线程仍未完成 save 操作,onResumeload 可能会读取旧数据。

经过多次实验,这是我对

的观察

JobScheduler

  1. 我们应该使用 android.support.v4.app.JobIntentService 而不是 JobScheduler。在底层,它将在 Android O 中使用 JobScheduler,在 Android O 之前使用 startService
  2. 取决于 OS。作业不会在 Android O 后立即开始。它可能 延迟多达 5 分钟 才开始作业。这是 JobScheduler 的预期行为。它根据资源可用性决定何时 运行 作业。
  3. 这份工作可以运行相当长的一段时间。我做了一个极端的例子,让作业 运行s 持续 10 分钟。没问题,除非您明确终止该应用程序。 (使用最近任务列表关闭应用)

意图服务

  1. 马上运行。
  2. 这份工作可以运行相当长的一段时间。我做了一个极端的例子,让作业 运行s 持续 10 分钟。没问题,除非您明确终止该应用程序。 (使用最近任务列表关闭应用)

尽管 Google 建议我们使用 JobScheduler

Note: If your app targets Android 5.0 (API level 21) or later, it's recommended that you use the JobScheduler to execute background services.

对于我的情况,我需要

  1. 我的任务最多执行 2 分钟。
  2. 我需要在应用退出后立即运行任务。我不想耽误它。

这就是我选择使用 IntentService 的原因。