安卓在API21的时候提供提供了一个JobScheduler 任务队列的东东。
来源:互联网 发布:java web项目高并发 编辑:程序博客网 时间:2024/04/29 04:46
Using the JobScheduler API on Android Lollipop
In this tutorial, you will learn how to use the JobScheduler
API available in Android Lollipop. The JobScheduler
API 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 JobScheduler
API to handle this very scenario.
The JobScheduler
API performs an operation for your application when a set of predefined conditions are met. Unlike the AlarmManager
class, the timing isn't exact. In addition, the JobScheduler
API 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 JobScheduler
API and the JobService
class 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 JobScheduler
API 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 JobService
class, which requires that two methods be created onStartJob(JobParameters params)
andonStopJob(JobParameters params)
.
public
class
JobSchedulerService
extends
JobService {
@Override
public
boolean
onStartJob(JobParameters params) {
return
false
;
}
@Override
public
boolean
onStopJob(JobParameters params) {
return
false
;
}
}
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 is false
, 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 is true
, 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 calling jobFinished(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 if onStartJob(JobParameters params)
returns false
, the system assumes there are no jobs currently running when a cancel request is received. In other words, it simply won't call onStopJob(JobParameters params)
.
One thing to note is that the job service runs on your application's main thread. This means that you have to use 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 JobSchedulerService
class.
private
Handler mJobHandler =
new
Handler(
new
Handler.Callback() {
@Override
public
boolean
handleMessage( Message msg ) {
Toast.makeText( getApplicationContext(),
"JobService task running"
, Toast.LENGTH_SHORT )
.show();
jobFinished( (JobParameters) msg.obj,
false
);
return
true
;
}
} );
In the handler, you implement the handleMessage(Message msg)
method that is a part of Handler
instance and have it run your task's logic. In this case, we're keeping things very simple and post a Toast
message 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 the JobParameters
that were passed to theJobService
class in the onStartJob(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 Handler
instance created, you can go ahead and start implementing theonStartJob(JobParameters params)
and onStopJob(JobParameters params)
methods to control your tasks. You'll notice that in the following code snippet, the onStartJob(JobParameters params)
method returns true
. This is because you're going to use a Handler
instance to control your operation, which means that it could take longer to finish than the onStartJob(JobParameters params)
method. By returning true
, you're letting the application know that you will manually call the jobFinished(JobParameters params, boolean needsRescheduled)
method. You'll also notice that the number 1
is being passed to the Handler
instance. This is the identifier that you're going to use for referencing the job.
@Override
public
boolean
onStartJob(JobParameters params) {
mJobHandler.sendMessage( Message.obtain( mJobHandler,
1
, params ) );
return
true
;
}
@Override
public
boolean
onStopJob(JobParameters params) {
mJobHandler.removeMessages(
1
);
return
false
;
}
Once you're done with the Java portion of the JobSchedulerService
class, you need to go into AndroidManifest.xml and add a node for the service so that your application has permission to bind and use this class as a JobService
.
<service android:name=
".JobSchedulerService"
android:permission=
"android.permission.BIND_JOB_SERVICE"
/>
2. Creating the Job Scheduler
With JobSchedulerService
class finished, we can start looking at how your application will interact with the JobScheduler
API. The first thing you will need to do is create aJobScheduler
object, called mJobScheduler
in the sample code, and initialize it by getting an instance of the system service JOB_SCHEDULER_SERVICE
. In the sample application, this is done in the MainActivity
class.
mJobScheduler = (JobScheduler)
getSystemService( Context.JOB_SCHEDULER_SERVICE );
When you want to create your scheduled task, you can use the JobInfo.Builder
to construct a JobInfo
object that gets passed to your service. To create a JobInfo
object, JobInfo.Builder
accepts 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 the JobScheduler
API.
JobInfo.Builder builder =
new
JobInfo.Builder(
1
,
new
ComponentName( 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.
builder.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 willcause 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)
and setRequiresDeviceIdle(boolean requireIdle)
may cause your job to never start unless setOverrideDeadline(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 the JobInfo
object and send it to yourJobScheduler
object as shown below.
if
( mJobScheduler.schedule( builder.build() ) <=
0
) {
//If something goes wrong
}
You'll notice that the schedule
operation returns an integer. If schedule
fails, 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 the JobInfo.Builder
.
If your application requires that you stop a specific or all jobs, you can do so by calling cancel(int jobId)
or cancelAll()
on the JobScheduler
object.
mJobScheduler.cancelAll();
You should now be able to use the JobScheduler
API with your own applications to batch jobs and run background operations.
Conclusion
In this article, you've learned how to implement a JobService
subclass that uses aHandler
object to run background tasks for your application. You've also learned how to use the JobInfo.Builder
to 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.
- 安卓在API21的时候提供提供了一个JobScheduler 任务队列的东东。
- 安卓在4.3的系统中提供了低功耗蓝牙Bluetooth Low Energy
- 提供了一个无效的参数 BluetoothListener
- spring提供的一个简单的任务执行时间监视器 StopWatch
- jdk提供的消息队列
- Android--安卓系统提供了什么
- 在做一个华为的企业信息机,短信服务商提供了个 接口 SMEntry.dll
- hadoop提供了一个跑在yarn上的示例,可以运行
- MySQL提供了自己的一个快速响应的实现
- C++第四周中提供了多种基本的数据类型(任务四)定义一个工资类
- ORACLE 提供了一个有趣的功能 connect by 子句
- apache 问题--提供了一个无效的参数!
- Servlets提供了一个CGI开发的简单替换方法
- ArcGIS9为栅格数据管理提供了一个完整的系统
- 转一个类: ESCursors提供了各种各样的箭头光标
- oracle提供了一个更强大的PROCEDURE DBMS_RANDOM过程
- 一个好网站 提供了很多总结性的文档
- Microsoft .NET终于提供了一个通用的Zip库
- .NET(C#) TPL:Task中未觉察异常和TaskScheduler.UnobservedTaskException事件
- 【ZendServer】Internal Server Error解决办法
- Swoole:重新定义PHP
- ios8 使用storyboard 进行自动布局(一)
- 重拾Android 之简单复习
- 安卓在API21的时候提供提供了一个JobScheduler 任务队列的东东。
- 一群高中生创建了eduITer,发布原创的IT技能课程视频,你有没有觉得汗颜?
- IT业人才发展最佳实践是什么
- 通知与消息机制
- 微观SOA:服务设计原则及其实践方式
- android timer的schedule和scheduleAtFixedRate运用
- 软件测试大概的思路
- Linux时间同步+国内常用的NTP服务器地址
- OC 3月29日学习总结