【问题标题】:IntentService or JobScheduler to perform I/O intensive data save operation during onPauseIntentService 或 JobScheduler 在 onPause 期间执行 I/O 密集型数据保存操作
【发布时间】:2018-02-07 16:55:15
【问题描述】:

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

private void save() {
    saveDataToFiles();
}

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

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

  • 将数据保存到 SQLite
  • 通过网络保存数据

因此,代码会演变成

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

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

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

我查看了How to execute background task when Android app is closed / set to background?(日期为 2016 年。因此,有些建议可能不再有效。)

我最初的计划是移动save()方法,由IntentService执行

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

不过,我也注意到来自 Google https://developer.android.com/guide/components/bound-services.html 的一些警告

注意:如果您的应用面向 Android 5.0(API 级别 21)或更高版本,则 建议你使用 JobScheduler 来执行后台 服务。

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

我的问题是

  1. onPause() 期间我应该使用JobScheduler 还是IntentService?我估计save() 的执行时间应该不会超过 10 秒。
  2. 我会面临数据不一致的问题吗?我该如何解决?考虑以下情况
    • onPause 触发。启动线程执行save
    • onResume 触发。加载器启动,执行load
    • 由于之前来自onPause 的线程仍未完成save 操作,来自onResumeload 可能会读取旧数据。

【问题讨论】:

    标签: android multithreading intentservice android-intentservice android-jobscheduler


    【解决方案1】:

    经过几次实验,这是我的观察结果

    作业调度器

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

    意图服务

    1. 它会立即运行。
    2. 作业可以运行相当长的时间。我做了一个极端的例子,让作业运行 10 分钟。除非您明确杀死该应用程序,否则没有问题。 (使用最近的任务列表关闭应用)

    尽管谷歌建议我们使用JobScheduler

    注意:如果您的应用面向 Android 5.0(API 级别 21)或更高版本,则 建议你使用 JobScheduler 来执行后台 服务。

    就我而言,我需要

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多