在Android 5.0中使用JobScheduler(转载)
翻译见:http://blog.csdn.net/bboyfeiyu/article/details/44809395
In this tutorial, you will learn how to use the
JobSchedulerAPI available in Android Lollipop. TheJobSchedulerAPI allows developers to create jobs that execute in the background when certain conditions are met.Introduction
When working with Android, there will be occasions where you will want to run a task at a later point in time or under certain conditions, such as when a device is plugged into a power source or connected to a Wi-Fi network. Thankfully with API 21, known by most people as Android Lollipop, Google has provided a new component known as the
JobSchedulerAPI to handle this very scenario.The
JobSchedulerAPI performs an operation for your application when a set of predefined conditions are met. Unlike theAlarmManagerclass, the timing isn't exact. In addition, theJobSchedulerAPI is able to batch various jobs to run together. This allows your app to perform the given task while being considerate of the device's battery at the cost of timing control.In this article, you will learn more about the
JobSchedulerAPI and theJobServiceclass by using them to run a simple background task in an Android application. The code for this tutorial is available on GitHub.1. Creating the Job Service
To start, you're going to want to create a new Android project with a minimum required API of 21, because the
JobSchedulerAPI was added in the most recent version of Android and, at the time of writing, is not backwards compatible through a support library.Assuming you're using Android Studio, after you've hit the finished button for the new project, you should have a bare-bones "Hello World" application. The first step you're going to take with this project is to create a new Java class. To keep things simple, let's name it JobSchedulerService and extend the
JobServiceclass, which requires that two methods be createdonStartJob(JobParameters params)andonStopJob(JobParameters params).
010203040506070809101112131415publicclassJobSchedulerServiceextendsJobService {@OverridepublicbooleanonStartJob(JobParameters params) {returnfalse;}@OverridepublicbooleanonStopJob(JobParameters params) {returnfalse;}}
onStartJob(JobParameters params)is the method that you must use when you begin your task, because it is what the system uses to trigger jobs that have already been scheduled. As you can see, the method returns a boolean value. If the return value isfalse, the system assumes that whatever task has run did not take long and is done by the time the method returns. If the return value istrue, then the system assumes that the task is going to take some time and the burden falls on you, the developer, to tell the system when the given task is complete by callingjobFinished(JobParameters params, boolean needsRescheduled).
onStopJob(JobParameters params)is used by the system to cancel pending tasks when a cancel request is received. It's important to note that ifonStartJob(JobParameters params)returnsfalse, the system assumes there are no jobs currently running when a cancel request is received. In other words, it simply won't callonStopJob(JobParameters params).One thing to note is that the job service runs on your application's main thread. This means that you have touse another thread, a handler, or an asynchronous task to run longer tasks to not block the main thread. Because multithreading techniques are beyond the scope of this tutorial, let's keep it simple and implement a handler to run our task in the
JobSchedulerServiceclass.
010203040506070809101112privateHandler mJobHandler =newHandler(newHandler.Callback() {@OverridepublicbooleanhandleMessage( Message msg ) {Toast.makeText( getApplicationContext(),"JobService task running", Toast.LENGTH_SHORT ).show();jobFinished( (JobParameters) msg.obj,false);returntrue;}} );In the handler, you implement the
handleMessage(Message msg)method that is a part ofHandlerinstance and have it run your task's logic. In this case, we're keeping things very simple and post aToastmessage from the application, though this is where you would put your logic for things like syncing data.When the task is done, you need to call
jobFinished(JobParameters params, boolean needsRescheduled)to let the system know that you're done with that task and that it can begin queuing up the next operation. If you don't do this, your jobs will only run once and your application will not be allowed to perform additional jobs.The two parameters that
jobFinished(JobParameters params, boolean needsRescheduled)takes are theJobParametersthat were passed to theJobServiceclass in theonStartJob(JobParameters params)method and a boolean value that lets the system know if it should reschedule the job based on the original requirements of the job. This boolean value is useful to understand, because it is how you handle the situations where your task is unable to complete because of other issues, such as a failed network call.With the
Handlerinstance created, you can go ahead and start implementing theonStartJob(JobParameters params)andonStopJob(JobParameters params)methods to control your tasks. You'll notice that in the following code snippet, theonStartJob(JobParameters params)method returnstrue. This is because you're going to use aHandlerinstance to control your operation, which means that it could take longer to finish than theonStartJob(JobParameters params)method. By returningtrue, you're letting the application know that you will manually call thejobFinished(JobParameters params, boolean needsRescheduled)method. You'll also notice that the number1is being passed to theHandlerinstance. This is the identifier that you're going to use for referencing the job.
0102030405060708091011@OverridepublicbooleanonStartJob(JobParameters params) {mJobHandler.sendMessage( Message.obtain( mJobHandler,1, params ) );returntrue;}@OverridepublicbooleanonStopJob(JobParameters params) {mJobHandler.removeMessages(1);returnfalse;}Once you're done with the Java portion of the
JobSchedulerServiceclass, you need to go intoAndroidManifest.xml and add a node for the service so that your application has permission to bind and use this class as aJobService.
12<service android:name=".JobSchedulerService"android:permission="android.permission.BIND_JOB_SERVICE"/>2. Creating the Job Scheduler
With
JobSchedulerServiceclass finished, we can start looking at how your application will interact with theJobSchedulerAPI. The first thing you will need to do is create aJobSchedulerobject, calledmJobSchedulerin the sample code, and initialize it by getting an instance of the system serviceJOB_SCHEDULER_SERVICE. In the sample application, this is done in theMainActivityclass.
12mJobScheduler = (JobScheduler)getSystemService( Context.JOB_SCHEDULER_SERVICE );When you want to create your scheduled task, you can use the
JobInfo.Builderto construct aJobInfoobject that gets passed to your service. To create aJobInfoobject,JobInfo.Builderaccepts two parameters. The first is the identifier of the job that you will run and the second is the component name of the service that you will use with theJobSchedulerAPI.
123JobInfo.Builder builder =newJobInfo.Builder(1,newComponentName( getPackageName(),JobSchedulerService.class.getName() ) );This builder allows you to set many different options for controlling when your job will execute. The following code snippet shows how you could set your task to run periodically every three seconds.
1builder.setPeriodic(3000);Other methods include:
setMinimumLatency(long minLatencyMillis): This makes your job not launch until the stated number of milliseconds have passed. This is incompatible withsetPeriodic(long time)and will cause an exception to be thrown if they are both used.setOverrideDeadline(long maxExecutionDelayMillis): This will set a deadline for your job. Even if other requirements are not met, your task will start approximately when the stated time has passed. LikesetMinimumLatency(long time), this function is mutually exclusive withsetPeriodic(long time)and will cause an exception to be thrown if they are both used.setPersisted(boolean isPersisted): This function tells the system whether your task should continue to exist after the device has been rebooted.setRequiredNetworkType(int networkType): This function will tell your job that it can only start if the device is on a specific kind of network. The default isJobInfo.NETWORK_TYPE_NONE, meaning that the task can run whether there is network connectivity or not. The other two available types areJobInfo.NETWORK_TYPE_ANY, which requires some type of network connection available for the job to run, andJobInfo.NETWORK_TYPE_UNMETERED, which requires that the device be on a non-cellular network.setRequiresCharging(boolean requiresCharging): Using this function will tell your application that the job should not start until the device has started charging.setRequiresDeviceIdle(boolean requiresDeviceIdle): This tells your job to not start unless the user is not using their device and they have not used it for some time.It's important to note that
setRequiredNetworkType(int networkType),setRequiresCharging(boolean requireCharging)andsetRequiresDeviceIdle(boolean requireIdle)may cause your job to never start unlesssetOverrideDeadline(long time)is also set, allowing your job to run even if conditions are not met. Once the preferred conditions are stated, you can build theJobInfoobject and send it to yourJobSchedulerobject as shown below.
123if( mJobScheduler.schedule( builder.build() ) <=0) {//If something goes wrong}You'll notice that the
scheduleoperation returns an integer. Ifschedulefails, it will return a value of zero or less, corresponding to an error code. Otherwise it will return the job identifier that we defined in theJobInfo.Builder.If your application requires that you stop a specific or all jobs, you can do so by calling
cancel(int jobId)orcancelAll()on theJobSchedulerobject.
1mJobScheduler.cancelAll();You should now be able to use the
JobSchedulerAPI with your own applications to batch jobs and run background operations.Conclusion
In this article, you've learned how to implement a
JobServicesubclass that uses aHandlerobject to run background tasks for your application. You've also learned how to use theJobInfo.Builderto set requirements for when your service should run. Using these, you should be able to improve how your own applications operate while being mindful of power consumption.
在Android 5.0中使用JobScheduler(转载)的更多相关文章
- 在Android 5.0中使用JobScheduler
在Android 5.0中使用JobScheduler 原文链接 : using-the-jobscheduler-api-on-android-lollipop 译者 : Mr.Simple 校对者 ...
- Android 5.0中使用JobScheduler
在这篇文章中,你会学习到在Android 5.0中怎样使用JobScheduler API. JobScheduler API同意开发人员在符合某些条件时创建运行在后台的任务. 介绍 在Android ...
- Android 7.0 中 ContentProvider 实现原理
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:汪毅雄 导语: 本文描述了ContentProvider发布者和调用者这两在Framework层是如何实现的. 作为Android的四大 ...
- 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:
我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...
- 我的Android进阶之旅------>怎样解决Android 5.0中出现的警告: Service Intent must be explicit:
我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...
- Android 6.0 中的 Wifi 连接
Android 6.0 中的 Wifi 连接 这几天在写一个软件,结果被其中的 wifi 连接问题困扰了 3 天. 先描述下需求: usb 接口接了一根 usb2serial,通过这个接口接收命令 当 ...
- android 4.0 中出错 java.lang.UnsupportedOperationException
在android4.0中 画图的时候使用: canvas.clipPath(path, Region.Op.XOR); 报错 java.lang.UnsupportedOperationExcept ...
- Android Studio3.0中dependencies依赖由compile变为implementation的区别
前言 Android Studio版本更新至3.0了,更新后,连带着com.android.tools.build:gradle 工具也升级到了3.0.0,在3.0.0中使用了最新的Gralde 4. ...
- Android 6.0 中TimePicker显示为滚动样式的方法
在Android6.0中,TimePicker控件的默认样式为转盘的样式,就像这个样子: 如果想要显示为之前的滚动样式的话也很简单,只要在布局文件中设置TimePicker的timePickerMod ...
随机推荐
- 把玩Javascript中的bind
前言 今天闲着无聊随便逛了逛MDN,忽而看到一个方法Function.prototype.bind(),突然发现除了使用这个方法之外都没有仔细琢磨过这个方法.于是乎,找到了kill time的事情-写 ...
- 潭州课堂25班:Ph201805201 爬虫基础 第十二课 点触验证码二 (课堂笔记)
为上次代码添加 模拟人操作 的鼠标的移动轨迹 # -*- coding:utf-8 -*- # 斌彬电脑 # @Time : 2018/9/14 0014 上午 8:08 from selenium ...
- 潭州课堂25班:Ph201805201 WEB 之 JS 第五课 (课堂笔记)
算数运算符 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- [模板][P3377]左偏树
Description: 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数 ...
- 【转载】IntelliJ IDEA 内存优化最佳实践
本文转自 http://blog.oneapm.com/apm-tech/426.html [编者按]本文作者在和同事的一次讨论中发现,对 IntelliJ IDEA 内存采用不同的设置方案,会对 I ...
- Unity Shader-后处理:简单均值模糊
一.简介 今天来学习一下后处理中比较常用的一种效果,屏幕模糊效果.模糊效果,在图像处理中经常用到,Photoshop中也有类似的滤镜.我们在游戏中也会经常用到.因为屏幕模糊效果是一些高级后处理效果 ...
- 给你的 CentOS 7 安装中文支持
今天给大家分享个给 CentOS 7 安装中文支持的方法,所谓“中文支持”目前明月观测到的是指命令行提示支持中文提示显示,还有就是 Vim 启动后看到的也是有中文提是的界面包括 Vim 内各种提示也会 ...
- RxJava2 源码解析(一)
概述 最近事情太多了,现在公司内部的变动,自己岗位的变化,以及最近决定找工作.所以博客耽误了,准备面试中,打算看一看RxJava2的源码,遂有了这篇文章. 不会对RxJava2的源码逐字逐句的阅读,只 ...
- Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法
更新Win10,原来的IIS站点访问不了,原因是因为IIS 没有.net 4.5,使用网上的aspnet_regiis.exe -i命令,一点都不靠谱,直接提示: C:\WINDOWS\system3 ...
- [Python]编码声明:是coding:utf-8还是coding=urf-8呢
推荐: #!/usr/bin/env python3 # -*- coding: utf-8 -*- 我们知道在Python源码的头文件中要声明编码方式,如果你不只是会用到ascii码,很多人都写得都 ...