翻译见:http://blog.csdn.net/bboyfeiyu/article/details/44809395

  • In this tutorial, you will learn how to use the JobScheduler API available in Android Lollipop. The JobSchedulerAPI 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 JobServiceclass, which requires that two methods be created onStartJob(JobParameters params) and onStopJob(JobParameters params).

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    publicclassJobSchedulerService extendsJobService {
        @Override
        publicbooleanonStartJob(JobParameters params) {
            returnfalse;
        }
        @Override
        publicbooleanonStopJob(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 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 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 JobSchedulerService class.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    privateHandler mJobHandler = newHandler( newHandler.Callback() {
        
        @Override
        publicbooleanhandleMessage( 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 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 JobParametersthat were passed to the JobService 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 the onStartJob(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 aHandler 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.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    @Override
    publicbooleanonStartJob(JobParameters params) {
        mJobHandler.sendMessage( Message.obtain( mJobHandler, 1, params ) );
        returntrue;
    }
    @Override
    publicbooleanonStopJob(JobParameters params) {
        mJobHandler.removeMessages( 1);
        returnfalse;
    }

    Once you're done with the Java portion of the JobSchedulerService class, 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 a JobService.

    1
    2
    <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 theJobScheduler API. The first thing you will need to do is create a JobScheduler 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.

    1
    2
    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.

    1
    2
    3
    JobInfo.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.

    1
    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 with setPeriodic(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 with setPeriodic(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 is JobInfo.NETWORK_TYPE_NONE, meaning that the task can run whether there is network connectivity or not. The other two available types are JobInfo.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 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 your JobScheduler object as shown below.

    1
    2
    3
    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) orcancelAll() on the JobScheduler object.

    1
    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 a Handler 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.

在Android 5.0中使用JobScheduler(转载)的更多相关文章

  1. 在Android 5.0中使用JobScheduler

    在Android 5.0中使用JobScheduler 原文链接 : using-the-jobscheduler-api-on-android-lollipop 译者 : Mr.Simple 校对者 ...

  2. Android 5.0中使用JobScheduler

    在这篇文章中,你会学习到在Android 5.0中怎样使用JobScheduler API. JobScheduler API同意开发人员在符合某些条件时创建运行在后台的任务. 介绍 在Android ...

  3. Android 7.0 中 ContentProvider 实现原理

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:汪毅雄 导语: 本文描述了ContentProvider发布者和调用者这两在Framework层是如何实现的. 作为Android的四大 ...

  4. 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  5. 我的Android进阶之旅------&gt;怎样解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  6. Android 6.0 中的 Wifi 连接

    Android 6.0 中的 Wifi 连接 这几天在写一个软件,结果被其中的 wifi 连接问题困扰了 3 天. 先描述下需求: usb 接口接了一根 usb2serial,通过这个接口接收命令 当 ...

  7. android 4.0 中出错 java.lang.UnsupportedOperationException

    在android4.0中  画图的时候使用: canvas.clipPath(path, Region.Op.XOR); 报错 java.lang.UnsupportedOperationExcept ...

  8. Android Studio3.0中dependencies依赖由compile变为implementation的区别

    前言 Android Studio版本更新至3.0了,更新后,连带着com.android.tools.build:gradle 工具也升级到了3.0.0,在3.0.0中使用了最新的Gralde 4. ...

  9. Android 6.0 中TimePicker显示为滚动样式的方法

    在Android6.0中,TimePicker控件的默认样式为转盘的样式,就像这个样子: 如果想要显示为之前的滚动样式的话也很简单,只要在布局文件中设置TimePicker的timePickerMod ...

随机推荐

  1. grpc 使用总结

    1.grpc支持多种语言,需要根据pb文件创建出相应java文件. 2.构建服务端. 3.构建客户端. 4.grpc对象基于创建者模式.

  2. unity3d 给游戏添加音源 Unity3d adds a sound source to the game

    unity3d 给游戏添加音源 Unity3d adds a sound source to the game   作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:3131345 ...

  3. Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)

    题目链接 \(Description\) 给定一棵树,每条边上有一个字符(a~v).对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串.输出其最长长度. \(n ...

  4. Python图形编程探索系列-07-程序登录界面设计

    设计任务 初步设计程序登录界面,详细分析设计步骤. 程序详细分析 基本框架设计 import tkinter as tk import tkinter.messagebox root = tk.Tk( ...

  5. C++ map<key , value> key值为指针

    STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的, map<string, int> mapStr; 为了追求效率,把string改成了c ...

  6. .net 企业管理系统快速搭建框架

          简言   本人在博客园注册也2年多了,一直没有写自己的博客,因为才疏学浅一直跟着园子里的大哥们学习这.net技术.一年之前跳槽到现在的公司工作,由于公司没有自己一套的开发框架,每次都要重新 ...

  7. C# Queue 和Stack的实现

    Queue 和Stack的使用就不用多说吧,一个是先进先出,一个是后进先出. 这里我主要关注其实现原理. queue的实现如下: public class Queue<T> : IEnum ...

  8. iframe实现Ajax文件上传效果示例

    <!doctype html> <html> <head> <meta charset=utf-8> <head> <title> ...

  9. ftrace 示例

    假设debugfs已经挂载到了/sys/kernel/debug目录下,下面的小脚本用来抓取unlink系统调用的耗时: cd /sys/kernel/debug/tracing echo funct ...

  10. OpenCV 学习笔记 06 图像检索以及基于图像描述符的搜索

    OpenCV 可以检测图像的主要特征,然后提取这些特征,使其成为图像描述符,这些图像特征可作为图像搜索的数据库:此外可以利用关键点将图像拼接 stitch 起来,组成一个更大的图像.如将各照片组成一个 ...