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"/>
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的情况,不容错过。有问题可以留言哟,大家一起探讨!
JobScheduler内部时序图
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!
我们在AWS环境中部署了完整的应用程序,我们发现AWS秘密管理器是存储数据库和其他一些组件的秘密的正确选择。
Pony ORM 实现了一个很有趣的功能:使用类似 Python 生成器的语法来创建数据库查询语句。 比如这样的代码: select( p for p in Person if p.name.startswith('Paul') ).order_by(Person.name)[:2] 会生成下面的 SQL 语句: SELECT "p"."id", "p"."name", "p"."age
我成功地实现了在terraform中创建敏感资源的流程,在任何时候都不会透露敏感细节是什么,因此在我们的github repo中不会以纯文本存储。我让TF创建一个服务帐户,它与SA密钥相关,然后创建一个引用SA密钥输出的GCP密钥。 我现在想看看是否有任何方法可以对一些预定义的数据库密码执行相同的操作。流量会略有不同: 手动创建GCP secret(在secrets manager中),该密码的值
我有一个用秘密定义的Azure密钥库,我可以使用“Azure密钥库”任务在devops构建管道中访问它。现在我需要将秘密变量传递给python内联脚本。 由于它是加密的,python无法直接读取该值。我如何解密并传递它们。这个秘密持有Databricks的访问令牌。我们正在尝试使用DevOps管道创建Databricks集群。 我的Yaml有以下任务 Azure KeyVault Powershe
在电池省电模式下,M600 的某些活动将减少,以延智能手表的电池寿命。电池省电模式将限制以下内容: 振动 位置服务 Wi-Fi 和移动使用率 数据和应用更新 息屏提醒 要打开/关闭电池省电模式 从主屏幕顶部向下滑动 轻触设置图标。 轻触系统。 轻触电池省电模式,在打开(开关为蓝色)和关闭(开关为灰色)间切换。 通过轻触复选标记图标,确认打开电池省电模式。
我正在尝试从使用文件,以使用谷歌云平台机密管理器。我已经按照这里的说明操作了,但是我遇到了一个错误,说我没有权限访问这个秘密。 这就是我得到的错误: 我确实创建了一个具有“所有者”权限的服务帐户,下载了它,并使其