app 耗电优化之三 使用JobSchedule对任务进行合理排期

本文详细介绍了Android 5.0及更高版本中引入的JobScheduler功能,包括如何利用它在网络变化、设备充电或空闲时执行任务,以及如何设定任务执行的具体时间。JobScheduler作为一种优化电池消耗的手段,为开发者提供了灵活的任务调度机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JobSchedule 是Android5.0之后添加进去的,之前的版本没有。
JobSchedule 原理是一种将任务安排在恰当的实际进行操作一种方案机制。具体提供了那些可选的时机,如下:
1 在可用网络下执行。在7.0 之前,应用可以通过监听网络变化来执行任务,当然了前提是应用必须存活。到7.0之后这类API已经失效,但是JobSchedule机制提供了网络变化的监听。进一步可以在网络变化的情况下执行某些操作。例如在wifi环境下执行下载任务等。
2 设备在充电或者空闲时执行一些任务。
3 设定执行的时间,这个和其他的条件(1,2)一起使用。
具体的实现如下:
1 任务排期

    final JobScheduler scheduler = context.getSystemService(JobScheduler.class);
    //或者
    final JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE );
    //如果当前的jobId已经被安排了则下取消该安排
    final int jobId = (int) info.mId;
    scheduler.cancel(jobId);
    //构建JobInfo  jobId 为jobID。DownloadJobService 为Job接受的Service,该Service必须继承JobService
    final JobInfo.Builder builder = new JobInfo.Builder(jobId,new ComponentName(context, DownloadJobService.class));
    //设置设备重启是执行此任务。前提是需要拥有RECEIVE_BOOT_COMPLETED  权限
    builder.setPriority(JobInfo.PRIORITY_FOREGROUND_APP);
    //这个设置并不能设置成为前台进程。通知还需要应用自己发。此外该设置会忽略该任务的网络限制。
    builder.setFlags(JobInfo.FLAG_WILL_BE_FOREGROUND);
    //设置任务延迟执行时间,不可与setPeriodic(long time)同时使用
    builder.setMinimumLatency(time);
    //设置设备执行的网络条件JobInfo.NETWORK_TYPE_UNMETERED 不计量网络(wifi),JobInfo.NETWORK_TYPE_NOT_ROAMING 非漫游网络, NETWORK_TYPE_ANY任何网络
    //JobInfo.NETWORK_TYPE_NONE 无论是否有网络都执行
    builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
    //设置在设备充电时执行
    builder.setRequiresCharging(true);
    //设置在设备空闲时间执行
    builder.setRequiresDeviceIdle(true);
    //循环没5秒执行一次
    builder.setPeriodic(5000);
    //约定的时间内的条件都没有被触发是5秒以后开始触发
    builder.setOverrideDeadline(5000);
    //生成Job
    JobInfo job = builder.build();
    //安排Job,该方法有返回值JobScheduler.RESULT_SUCCESS 表示安排成功,JobScheduler.RESULT_FAILURE 安排失败
    scheduler.schedule(job)
    //安排Job, packageName 表示那个应用安排的Job(耗电记这个应用的)。 userId表示谁安排的Job
    scheduler.scheduleAsPackage(builder.build(), packageName, UserHandle.myUserId(), TAG);

2 处理任务。
 当任务安排下去,应该会被记录在JobScheduler服务里面。当条件满足时,处理job对应的JobService会被启动,否则。。。
 首先定义JobService

<service
        android:name=".DownloadJobService"
        android:exported="true"  //这个地方必须是True,否则外界的应用无法启动该JobService
        android:permission="android.permission.BIND_JOB_SERVICE" //必须定义这个权限,你懂得
    />
public class DownloadJobService extends JobService {
        //开始执行Job接口。(必须实现)如果返回false则表示这个Job已经被执行完毕。如果true则表示这个Job正在被执行。
        public boolean onStartJob(JobParameters params) {
            final int id = params.getJobId();
            ....开始执行Job
            
            1 对于一个瞬间能够完成的任务,此处可以return false. 
            2 如果是耗时任务,则需要在异步线程中执行,并且返回true。此外
            myHandler.removeMessages(id);
            myHandler.sendEmptyMessage(id);
            执行完后不要忘记执行jobFinished
        }
        
        //Job执行停止,必须实现 ,当接收到任务取消时,如果该任务没有被结束,则执行该方法,否则不执行。
        public boolean onStopJob(JobParameters params) {
            //当然此处可以重新安排被取消的任务。
            scheduler.schedule(job)
        }
        //还有一个方法。jobFinished(JobParameters params, boolean needsRescheduled) 该方法是在任务执行完成时通知系统(不代表任务被执行成功)。needsRecheduled表示该任务是否被重复执行。
        //例如onStartJob执行结果是True。则实际上任务还在执行。这时候如果任务执行完了。就必须调用这个方法否则后面的任务。
        
    }

总结,Scheduler是一套提供给开发者的一套优化耗电的任务安排方式,还是相当不错的。

 

其他耗电优化方式请看  app耗电优化

 

转载于:https://www.cnblogs.com/ouyanliu/p/7220279.html

在 Java 中,我们可以使用 `JobSchedule` 类似的功能来实现定时任务调度,并启动项目执行线程完成特定的工作。虽然 Java 标准库本身并没有直接提供名为 `JobSchedule` 的类,但我们通常可以通过 `ScheduledExecutorService` 或第三方框架(如 Quartz Scheduler)来实现类似的效果。 ### 使用 `ScheduledExecutorService` 这是标准 JDK 提供的一种简单而强大的方式来实现定时任务调度以及线程管理。 #### 示例代码 ```java import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class JobSchedulerExample { public static void main(String[] args) { // 创建一个单线程的 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); // 定义需要定执行的任务 Runnable jobTask = () -> { System.out.println("任务线程正在运行 - " + Thread.currentThread().getName()); performJob(); // 执行实际业务逻辑 }; // 延迟1秒后开始第一次任务,之后每隔3秒执行一次 scheduler.scheduleAtFixedRate(jobTask, 1, 3, TimeUnit.SECONDS); System.out.println("主程序继续其他业务处理..."); } private static void performJob() { // 这里的代码表示具体的任务内容 try { System.out.println("模拟耗时任务开始"); Thread.sleep(2000); // 模拟长时间运行任务 System.out.println("模拟耗时任务结束"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("任务被打断:" + e.getMessage()); } } } ``` 在这段代码中: - 我们创建了 `ScheduledExecutorService` 来负责周性的任务调度。 - 配置好延迟时间和间隔时间(这里分别是 1 秒和 3 秒),让任务按照指定的时间规律反复执行。 - 主线程不会阻塞在这里,而是可以继续往下走。 --- ### 使用 Quartz 调度器 Quartz 是一种更强大、功能丰富的开源作业调度框架。它可以满足复杂的定时任务场景需求。 #### 引入依赖(Maven) 首先添加 Maven 依赖到项目的 `pom.xml` 文件: ```xml <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> ``` #### 示例代码 ```java import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; public class QuartzJobScheduler { public static void main(String[] args) throws SchedulerException { // 第一步:定义 JobDetail,描述具体要执行的任务 JobDetail jobDetail = JobBuilder.newJob(MyJob.class) .withIdentity("job1", "group1") .build(); // 第二步:定义 Trigger,控制何时及多久触发任务 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger1", "group1") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(5).repeatForever()) .build(); // 第三步:获取调度器实例 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 启动调度器 scheduler.start(); // 将 Job 和 Trigger 注册进调度器 scheduler.scheduleJob(jobDetail, trigger); System.out.println("Quartz Scheduler 已经成功启动..."); } // 自定义 Job 接口的具体实现 public static class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("MyJob 正在运行..." + Thread.currentThread().getName()); performJob(); } private void performJob() { try { System.out.println("模拟复杂计算任务开始"); Thread.sleep(2000); System.out.println("模拟复杂计算任务结束"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("任务被打断:" + e.getMessage()); } } } } ``` 在这段代码中: - **Job** 表示的是你要执行的实际任务; - **Trigger** 决定了什么时候去触发动这个任务; - 最终通过 `Scheduler` 把它们联系起来形成完整的调度流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值