Job Scheduler

在应用开发中,有以下一些常见的耗电场景:

  • 经常为了使一些特殊模块正常工作,而通过唤醒 CPU 去执行对应程序,但 Google 测试发现,每次唤醒 CPU,即使程序只运行 1 秒钟,但实际上消耗了大约两分钟的耗电量。
  • 一些并不重要的数据,在非 Wi-Fi 环境下上报,如上传日志等。
  • 在 CPU 高负荷状态下去做一些数据清理工作。

以上这些操作在应用中是有必要的,但并不紧急,可以选择在合适的环境下完成,因此Google 为了提高电池的续航能力,在 Android 5.0(API 21)提供了一个 JobScheduler 组件,只有一系列的预置条件满足时,才执行对应的操作,这样既能省电,又保证了功能的完整性。也就是说可以将不紧急的任务交给 Job Scheduler 来处理,Job Scheduler 集中处理收到的任务,选择合适的时间、合适的网络,再一起进行执行。

在以下场景可以考虑使用 Job Scheduler:

  • 重要不紧急的任务,可以延迟执行,如定期数据库数据更新和数据上报。
  • 耗电量较大的任务,比如充电时才希望执行的备份数据操作。
  • 不紧急可以不执行的网络任务,如在 Wi-Fi 环境预加载数据。
  • 可以批量执行的任务。

使用 JobScheduler 主要两个步骤,创建一个 JobScheduler 对象预设置任务执行条件以及创建 Job Service 执行具体的任务,接下来详细介绍使用方法。

  • 创建 JobScheduler
    创建 JobScheduler,用来初始化一个 JobScheduler 以及设置触发 JobScheduler 执行任务的条件。

1)通过 getSystemService()获取一个 JobScheduler 的对象:
2)创建一个 JobInfo,描述一个任务的执行 ID,以及触发这个任务的条件。

public class JobScheduleManager {
    private Context mContext;

    private JobScheduler jobScheduler;

    public JobScheduleManager(Context mContext) {
        this.mContext = mContext;
        jobScheduler = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    }

    public boolean addJobScheduleTask(int taskId) {
        JobInfo.Builder builder = new JobInfo.Builder(taskId, new ComponentName(mContext.getPackageName(), JobScheduleService.class.getName()));
        switch (taskId) {
            case 1:
                builder.setPeriodic(1000);
                break;
            case 2:
                builder.setPersisted(false);
                break;
            default:
                break;
        }
        if (jobScheduler != null) {
            return this.jobScheduler.schedule(builder.build()) > 0;
        }
        return false;
    }

}

从代码看到,首先通过 JobInfo 的 build 方法创建一个 JobInfo,有两个参数,第一个参数 task_id 是任务 ID,这个 ID 有两个作用:

  • 添加任务时,对不同的 ID 做不同的触发条件,即用 switch 代码实现。
  • 在执行时需要根据任务 ID 执行具体的任务。

第二个参数 ComponentName 是具体执行 JobSchedluer 任务的服务,参数为进程包名以及服务类名。
在 switch 代码段中,针对不同的任务设置不同的触发条件,JobInfo 支持以下触发条件:

在 switch 代码段中,针对不同的任务设置不同的触发条件,JobInfo 支持以下触发条件:

  • setMinimumLatency(long minLatencyMillis):设置任务的延迟执行时间(单位是 ms),需要注意的是,setMinimumLatency 与 setPeriodic(long time)方法不兼容,同时调用这两个方法会引起异常。
  • setOverrideDeadline(long maxExecutionDelayMillis):设置任务最晚的延迟时间。如果到了规定的时间,其他条件还未满足,这个任务也会被启动。与 setMinimumLatency (long time)一样,setOverrideDeadline 与 setPeriodic(long time)同时调用会引发异常。
  • setPersisted(boolean isPersisted):设备重启之后,任务是否还要继续执行。
  • setRequiredNetworkType(int networkType):只有在满足指定的网络条件时,才会被执行。共有三种类型:
  • JobInfo.NETWORK_TYPE_NONE:不管是否有网络,这个任务都会被执行(如果未设置,这个参数就是默认参数)。
  • JobInfo.NETWORK_TYPE_ANY:只有在有网络的情况下,任务才可以执行,和网络类型无关。
  • JobInfo.NETWORK_TYPE_UNMETERED:非运营商网络(比如在 Wi-Fi 连接时),时任务才会被执行。
  • setRequiresCharging(boolean requiresCharging):只有当设备在充电时,这个任务才会被执行。
  • setRequiresDeviceIdle(boolean requiresDeviceIdle):只有当用户没有在使用该设备且有一段时间没有使用时,才会启动该任务。

setRequiredNetworkType (int networkType)、setRequiresCharging (booleanrequireCharging)and setRequiresDeviceIdle(boolean requireIdle)这几个方法可能会使任务无法执行,除非调用 setOverrideDeadline(long time)设置了最大延迟时间,使任务在为满足条件的情况下也会被执行。

这样就完成添加一个任务到 JobScheduler 中。在添加一个任务时,要指定一个完成任务的 Service,JobSchedulerService,在任务条件触发后,进入JobSchedulerService 执行具体的工作。接下来实现一个 JobService,也就是 JobSchedulerService。

public class JobScheduleService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {
        // 具体执行的任务
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        // 取消一个任务
        return false;
    }
}

        <service
            android:name=".JobScheduleService"
            android:permission="android.permission.BIND_JOB_SERVICE">


        </service>

JobSchedulerService 类必须实现两个方法 onStartJob(JobParameters params)和 onStopJob(JobParameters params)。

(1)onStartJob(JobParameters params)

任务开始时,执行 onStartJob(JobParameters params)方法,系统用来触发已经被执行的 任 务 。 任 务 执 行 完 毕 , 需 要 调 用 jobFinished ( JobParameters params , booleanneedsRescheduled)来通知系统。

(2)void jobFinished(JobParameters params,boolean needsReschedule)

任务执行完后,调用 jobFinished 方法通知 JobScheduler。

(3)onStopJob(JobParameters params)

系统接收到一个取消请求时,调用 onStopJob(JobParameters params)方法取消正在等待执行的任务。如果系统在接收到一个取消请求时,实际任务队列中已经没有正在运行的任务,onStopJob(JobParameters params)不会被调用。

注意 JobService 运行在主线程,如果是耗时任务,一定要使用 ThreadHandler或者一个异步任务来运行耗时的操作,以防止阻塞主线程。

发布了119 篇原创文章 · 获赞 28 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/ldxlz224/article/details/101272337
job