欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android省电的秘密之JobScheduler

程序员文章站 2023-12-19 14:07:16
jobscheduler是android l版本新引入的api,jobscheduler,顾名思义,是用来调度工作。工作被调度的条件包括网络变化,充电插拔,周期执行等。使用...

jobscheduler是android l版本新引入的api,jobscheduler,顾名思义,是用来调度工作。工作被调度的条件包括网络变化,充电插拔,周期执行等。使用场景包括wifi条件下数据下载上传等等。谷歌为什么要引入这个新的api呢?是为了省电而制定的一种规范。想想如果每个开发者都利用这个api进行wifi网络下数据上传,数据上传的操作将会被统一到同一个时间点,批量处理,这样比许多应用单独唤醒要省电的多。

下面展示一个小例子

主mainactivity

builder.setrequirednetworktype(jobinfo.network_type_unmetered); 代表免费的网络,通常就是指wifi了

public class mainactivity extends activity {
 jobscheduler js;
 jobinfo.builder builder;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  js=(jobscheduler) getsystemservice(context.job_scheduler_service);
  builder=new builder(1, new componentname(this, demoservice.class));
  builder.setrequirednetworktype(jobinfo.network_type_unmetered);
  js.schedule(builder.build());
 }
}

需要被调度的job

当wifi可用时,这个demoservice 就会执行onstartjob

public class demoservice extends jobservice{
 @override
 public boolean onstartjob(jobparameters params) {
  // todo auto-generated method stub
  final jobparameters mjobparameters=params;
  asynctask<void, void, void> mtask = new asynctask<void, void, void>() {
  @override
  protected void doinbackground(void... params) {
   // todo auto-generated method stub
   return null;
  }
  @override
  protected void onpostexecute(void result) {
   // todo auto-generated method stub
   toast.maketext(wenfengservice.this, "hello", 1000).show();
   jobfinished(mjobparameters, true);
   super.onpostexecute(result);
  }
  };
  mtask.execute();
  return true;
 }
 @override
 public boolean onstopjob(jobparameters params) {
  // todo auto-generated method stub
  toast.maketext(this, "bye", 1000).show();
  return true;
 }
}

清单

<service
 android:name=".demoservice "
android:permission="android.permission.bind_job_service"
 android:exported="true"/>

Android省电的秘密之JobScheduler

onstartjob.png

onstartjob函数常常有两种场景

1.不耗时的操作,这时你应该返回false

2.耗时的操作例如数据下载等,这是你应该开启一个新线程(因为jobservice是跑在主线程的),并且返回true

如果调度是任务执行失败了,怎么办?

任务失败的情况有很多,例如下载失败了,例如下载过程wifi断掉了。

没问题,google提供了方便的重新调度的方法。

例如如果下载过程中,wifi断掉了,jobservice会回调onstopjob函数,这是只需要把函数的返回值设置为true就可以了。当wifi重新连接后,jobservice会重新回调onstartjob函数。

而如果下载失败了,例如上面的例子中的asynctask执行失败,怎么办呢?我们只需要在asynctask的onpostexecute中执行jobfinished(mjobparameters, true),这里的true代表任务要在wifi条件重新满足情况下重新调度。经典的写法如下。

开始调度

@override
public boolean onstartjob(final jobparameters params) {
 mdownloadartworktask = new downloadartworktask(this) {
 @override
 protected void onpostexecute(boolean success) {
  jobfinished(params, !success);
 }
 };
 mdownloadartworktask.execute();
 return true;
}

停止调度

@override
public boolean onstopjob(final jobparameters params) {
 if (mdownloadartworktask != null) {
 mdownloadartworktask.cancel(true);
 }
 return true;
}

如果调度的任务老是执行失败,怎么办?

为了省电的考虑,失败的任务在执行条件满足的情况下,要延时一段时间才能执行。而且随着失败次数的增多,延时会越长。举个例子,因为wifi断开而执行失败的任务,在wifi连上后不会马上执行,延时一段时间才能执行。

延时时间=30s*失败次数。

下图是jobscheduler在framework层的时序图,下一章将用adb指令直观查看jobscheduler的情况,不容错过。有问题可以留言哟,大家一起探讨!

Android省电的秘密之JobScheduler

jobscheduler内部时序图

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!

上一篇:

下一篇: