Android 5.0的调度作业JobScheduler
2016-05-13 17:03
453 查看
http://blog.csdn.net/cuiran/article/details/42805057
Android 5.0 提供了一个新的
首先看一下官方JobScheduler的API https://developer.android.com/reference/android/app/job/JobScheduler.html
This is an API for scheduling various types of jobs against the framework that will be executed in your application's own process.
这是一个API调度框架,将在您的应用程序的进程中执行的工作。
See
more description of the types of jobs that can be run and how to construct them. You will construct these JobInfo objects and pass them to the JobScheduler with
When the criteria declared are met, the system will execute this job on your application's
You identify which JobService is meant to execute the logic for your job when you create the JobInfo with
看到Jobinfo的更多的描述类型的工作,可以运行,以及如何构建。你可以构造这些JobInfo对象,并且使用schedule(JobInfo)在JobScheduler。
当符合标准声明,系统将执行调度在你的应用程序Jobservice。
The framework will be intelligent about when you receive your callbacks, and attempt to batch and defer them as much as possible. Typically if you don't specify a deadline on your job, it can be run at any moment depending on the current state of the JobScheduler's
internal queue, however it might be deferred as long as until the next time the device is connected to a power source.
You do not instantiate this class directly; instead, retrieve it through
作业调度在下列情况下非常有用:
应用具有您可以推迟的非面向用户的工作。
应用具有当插入设备时您希望优先执行的工作。
应用具有需要访问网络或 Wi-Fi 连接的任务。
应用具有您希望作为一个批次定期运行的许多任务。
工作单元由一个
使用
当设备充电时启动
当设备连接到不限流量网络时启动
当设备空闲时启动
在特定的截止期限之前或以最小的延迟完成
例如,您可以添加如下代码以在不限流量网络上运行您的任务:
如果设备具有稳定的电源(也就是说,它已插入了 2 分钟以上并且电池处于健康水平),则系统将运行任何已就绪可运行的已调度作业,即使作业的截止期限尚未到期也是如此。
这里可以在看一下官方给出的 JobService API
Entry point for the callback from the
This is the base class that handles asynchronous requests that were previously scheduled. You are responsible for overriding
which is where you will implement your job logic.
This service executes each incoming job on a
on your application's main thread. This means that you must offload your execution logic to another thread/handler/
your choosing. Not doing so will result in blocking any future callbacks from the JobManager - specifically
which is meant to inform you that the scheduling requirements are no longer being met.
所提供的方法如下
下面可以看一下官方给出的一个sample
运行效果如下
Activity如下
[java] view
plain copy
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.jobscheduler.service.TestJobService;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int MSG_UNCOLOUR_START = 0;
public static final int MSG_UNCOLOUR_STOP = 1;
public static final int MSG_SERVICE_OBJ = 2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_main);
Resources res = getResources();
defaultColor = res.getColor(R.color.none_received);
startJobColor = res.getColor(R.color.start_received);
stopJobColor = res.getColor(R.color.stop_received);
// Set up UI.
mShowStartView = (TextView) findViewById(R.id.onstart_textview);
mShowStopView = (TextView) findViewById(R.id.onstop_textview);
mParamsTextView = (TextView) findViewById(R.id.task_params);
mDelayEditText = (EditText) findViewById(R.id.delay_time);
mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
mServiceComponent = new ComponentName(this, TestJobService.class);
// Start service and provide it a way to communicate with us.
Intent startServiceIntent = new Intent(this, TestJobService.class);
startServiceIntent.putExtra("messenger", new Messenger(mHandler));
startService(startServiceIntent);
}
// UI fields.
int defaultColor;
int startJobColor;
int stopJobColor;
private TextView mShowStartView;
private TextView mShowStopView;
private TextView mParamsTextView;
private EditText mDelayEditText;
private EditText mDeadlineEditText;
private RadioButton mWiFiConnectivityRadioButton;
private RadioButton mAnyConnectivityRadioButton;
private CheckBox mRequiresChargingCheckBox;
private CheckBox mRequiresIdleCheckbox;
ComponentName mServiceComponent;
/** Service object to interact scheduled jobs. */
TestJobService mTestService;
private static int kJobId = 0;
Handler mHandler = new Handler(/* default looper */) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UNCOLOUR_START:
mShowStartView.setBackgroundColor(defaultColor);
break;
case MSG_UNCOLOUR_STOP:
mShowStopView.setBackgroundColor(defaultColor);
break;
case MSG_SERVICE_OBJ:
mTestService = (TestJobService) msg.obj;
mTestService.setUiCallback(MainActivity.this);
}
}
};
private boolean ensureTestService() {
if (mTestService == null) {
Toast.makeText(MainActivity.this, "Service null, never got callback?",
Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**
* UI onclick listener to schedule a job. What this job is is defined in
* TestJobService#scheduleJob().
*/
public void scheduleJob(View v) {
if (!ensureTestService()) {
return;
}
JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
String delay = mDelayEditText.getText().toString();
if (delay != null && !TextUtils.isEmpty(delay)) {
builder.setMinimumLatency(Long.valueOf(delay) * 1000);
}
String deadline = mDeadlineEditText.getText().toString();
if (deadline != null && !TextUtils.isEmpty(deadline)) {
builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
}
boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
if (requiresUnmetered) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requiresAnyConnectivity) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
mTestService.scheduleJob(builder.build());
}
/**
* cancel All jobs
* @param v
*/
public void cancelAllJobs(View v) {
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.cancelAll();
}
/**
* UI onclick listener to call jobFinished() in our service.
*/
public void finishJob(View v) {
if (!ensureTestService()) {
return;
}
mTestService.callJobFinished();
mParamsTextView.setText("");
}
/**
* Receives callback from the service when a job has landed
* on the app. Colours the UI and post a message to
* uncolour it after a second.
*/
public void onReceivedStartJob(JobParameters params) {
mShowStartView.setBackgroundColor(startJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
}
/**
* Receives callback from the service when a job that
* previously landed on the app must stop executing.
* Colours the UI and post a message to uncolour it after a
* second.
*/
public void onReceivedStopJob() {
mShowStopView.setBackgroundColor(stopJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
mParamsTextView.setText("");
}
}
然后新建一个类继承JobService
[java] view
plain copy
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler.service;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import com.example.android.jobscheduler.MainActivity;
import java.util.LinkedList;
/**
* Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler
* ultimately land on this service's "onStartJob" method. Currently all this does is post a message
* to the app's main activity to change the state of the UI.
*/
public class TestJobService extends JobService {
private static final String TAG = "SyncService";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service created");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroyed");
}
/**
* When the app's MainActivity is created, it starts this service. This is so that the
* activity and this service can communicate back and forth. See "setUiCalback()"
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Messenger callback = intent.getParcelableExtra("messenger");
Message m = Message.obtain();
m.what = MainActivity.MSG_SERVICE_OBJ;
m.obj = this;
try {
callback.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Error passing service object back to activity.");
}
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
// We don't do any real 'work' in this sample app. All we'll
// do is track which jobs have landed on our service, and
// update the UI accordingly.
jobParamsMap.add(params);
if (mActivity != null) {
mActivity.onReceivedStartJob(params);
}
Log.i(TAG, "on start job: " + params.getJobId());
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
// Stop tracking these job parameters, as we've 'finished' executing.
jobParamsMap.remove(params);
if (mActivity != null) {
mActivity.onReceivedStopJob();
}
Log.i(TAG, "on stop job: " + params.getJobId());
return true;
}
MainActivity mActivity;
private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
public void setUiCallback(MainActivity activity) {
mActivity = activity;
}
/** Send job to the JobScheduler. */
public void scheduleJob(JobInfo t) {
Log.d(TAG, "Scheduling job");
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(t);
}
/**
* Not currently used, but as an exercise you can hook this
* up to a button in the UI to finish a job that has landed
* in onStartJob().
*/
public boolean callJobFinished() {
JobParameters params = jobParamsMap.poll();
if (params == null) {
return false;
} else {
jobFinished(params, false);
return true;
}
}
}
具体详细代码可以参考下载的sdk里面
Android 5.0 提供了一个新的
JobSchedulerAPI,它允许您通过为系统定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命。
首先看一下官方JobScheduler的API https://developer.android.com/reference/android/app/job/JobScheduler.html
This is an API for scheduling various types of jobs against the framework that will be executed in your application's own process.
这是一个API调度框架,将在您的应用程序的进程中执行的工作。
See
JobInfofor
more description of the types of jobs that can be run and how to construct them. You will construct these JobInfo objects and pass them to the JobScheduler with
schedule(JobInfo).
When the criteria declared are met, the system will execute this job on your application's
JobService.
You identify which JobService is meant to execute the logic for your job when you create the JobInfo with
JobInfo.Builder(int, android.content.ComponentName).
看到Jobinfo的更多的描述类型的工作,可以运行,以及如何构建。你可以构造这些JobInfo对象,并且使用schedule(JobInfo)在JobScheduler。
当符合标准声明,系统将执行调度在你的应用程序Jobservice。
The framework will be intelligent about when you receive your callbacks, and attempt to batch and defer them as much as possible. Typically if you don't specify a deadline on your job, it can be run at any moment depending on the current state of the JobScheduler's
internal queue, however it might be deferred as long as until the next time the device is connected to a power source.
You do not instantiate this class directly; instead, retrieve it through
Context.getSystemService(Context.JOB_SCHEDULER_SERVICE).
作业调度在下列情况下非常有用:
应用具有您可以推迟的非面向用户的工作。
应用具有当插入设备时您希望优先执行的工作。
应用具有需要访问网络或 Wi-Fi 连接的任务。
应用具有您希望作为一个批次定期运行的许多任务。
工作单元由一个
JobInfo对象进行封装。此对象指定了调度条件。官方的API如下
Public Methods | |
---|---|
int | describeContents() Describe the kinds of special objects contained in this Parcelable's marshalled representation. |
int | getBackoffPolicy() One of either BACKOFF_POLICY_EXPONENTIAL, or BACKOFF_POLICY_LINEAR, depending on which criteria you set when creating this job. |
PersistableBundle | getExtras() Bundle of extras which are returned to your application at execution time. |
int | getId() Unique job id associated with this class. |
long | getInitialBackoffMillis() The amount of time the JobScheduler will wait before rescheduling a failed job. |
long | getIntervalMillis() Set to the interval between occurrences of this job. |
long | getMaxExecutionDelayMillis() See setOverrideDeadline(long). |
long | getMinLatencyMillis() Set for a job that does not recur periodically, to specify a delay after which the job will be eligible for execution. |
int | getNetworkType() One of NETWORK_TYPE_ANY, NETWORK_TYPE_NONE, or NETWORK_TYPE_UNMETERED. |
ComponentName | getService() Name of the service endpoint that will be called back into by the JobScheduler. |
boolean | isPeriodic() Track whether this job will repeat with a given period. |
boolean | isPersisted() |
boolean | isRequireCharging() Whether this job needs the device to be plugged in. |
boolean | isRequireDeviceIdle() Whether this job needs the device to be in an Idle maintenance window. |
String | toString() Returns a string containing a concise, human-readable description of this object. |
void | writeToParcel(Parcel out, int flags) Flatten this object in to a Parcel. |
JobInfo.Builder类配置调度的任务应当如何运行。您可以将任务调度为在特定的条件下运行,例如:
当设备充电时启动
当设备连接到不限流量网络时启动
当设备空闲时启动
在特定的截止期限之前或以最小的延迟完成
例如,您可以添加如下代码以在不限流量网络上运行您的任务:
<span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pln" style="color: rgb(0, 0, 0);"> uploadTask </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">Builder</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mJobId</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> mServiceComponent </span><span class="com">/* JobService component */</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setRequiredNetworkCapabilities</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">NetworkType</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">UNMETERED</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">build</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pln" style="color: rgb(0, 0, 0);"> jobScheduler </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">getSystemService</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">Context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">JOB_SCHEDULER_SERVICE</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> jobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">schedule</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">uploadTask</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>
如果设备具有稳定的电源(也就是说,它已插入了 2 分钟以上并且电池处于健康水平),则系统将运行任何已就绪可运行的已调度作业,即使作业的截止期限尚未到期也是如此。
这里可以在看一下官方给出的 JobService API
Entry point for the callback from the
JobScheduler.
This is the base class that handles asynchronous requests that were previously scheduled. You are responsible for overriding
onStartJob(JobParameters),
which is where you will implement your job logic.
This service executes each incoming job on a
Handlerrunning
on your application's main thread. This means that you must offload your execution logic to another thread/handler/
AsyncTaskof
your choosing. Not doing so will result in blocking any future callbacks from the JobManager - specifically
onStopJob(android.app.job.JobParameters),
which is meant to inform you that the scheduling requirements are no longer being met.
所提供的方法如下
final void | jobFinished(JobParameters params, boolean needsReschedule) Callback to inform the JobManager you've finished executing. 当完成执行后,通知调度管理器 |
abstract boolean | onStartJob(JobParameters params) Override this method with the callback logic for your job. |
abstract boolean | onStopJob(JobParameters params) This method is called if the system has determined that you must stop execution of your job even before you've had a chance to call jobFinished(JobParameters, boolean). |
运行效果如下
Activity如下
[java] view
plain copy
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.jobscheduler.service.TestJobService;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int MSG_UNCOLOUR_START = 0;
public static final int MSG_UNCOLOUR_STOP = 1;
public static final int MSG_SERVICE_OBJ = 2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_main);
Resources res = getResources();
defaultColor = res.getColor(R.color.none_received);
startJobColor = res.getColor(R.color.start_received);
stopJobColor = res.getColor(R.color.stop_received);
// Set up UI.
mShowStartView = (TextView) findViewById(R.id.onstart_textview);
mShowStopView = (TextView) findViewById(R.id.onstop_textview);
mParamsTextView = (TextView) findViewById(R.id.task_params);
mDelayEditText = (EditText) findViewById(R.id.delay_time);
mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
mServiceComponent = new ComponentName(this, TestJobService.class);
// Start service and provide it a way to communicate with us.
Intent startServiceIntent = new Intent(this, TestJobService.class);
startServiceIntent.putExtra("messenger", new Messenger(mHandler));
startService(startServiceIntent);
}
// UI fields.
int defaultColor;
int startJobColor;
int stopJobColor;
private TextView mShowStartView;
private TextView mShowStopView;
private TextView mParamsTextView;
private EditText mDelayEditText;
private EditText mDeadlineEditText;
private RadioButton mWiFiConnectivityRadioButton;
private RadioButton mAnyConnectivityRadioButton;
private CheckBox mRequiresChargingCheckBox;
private CheckBox mRequiresIdleCheckbox;
ComponentName mServiceComponent;
/** Service object to interact scheduled jobs. */
TestJobService mTestService;
private static int kJobId = 0;
Handler mHandler = new Handler(/* default looper */) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UNCOLOUR_START:
mShowStartView.setBackgroundColor(defaultColor);
break;
case MSG_UNCOLOUR_STOP:
mShowStopView.setBackgroundColor(defaultColor);
break;
case MSG_SERVICE_OBJ:
mTestService = (TestJobService) msg.obj;
mTestService.setUiCallback(MainActivity.this);
}
}
};
private boolean ensureTestService() {
if (mTestService == null) {
Toast.makeText(MainActivity.this, "Service null, never got callback?",
Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**
* UI onclick listener to schedule a job. What this job is is defined in
* TestJobService#scheduleJob().
*/
public void scheduleJob(View v) {
if (!ensureTestService()) {
return;
}
JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
String delay = mDelayEditText.getText().toString();
if (delay != null && !TextUtils.isEmpty(delay)) {
builder.setMinimumLatency(Long.valueOf(delay) * 1000);
}
String deadline = mDeadlineEditText.getText().toString();
if (deadline != null && !TextUtils.isEmpty(deadline)) {
builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
}
boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
if (requiresUnmetered) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requiresAnyConnectivity) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
mTestService.scheduleJob(builder.build());
}
/**
* cancel All jobs
* @param v
*/
public void cancelAllJobs(View v) {
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.cancelAll();
}
/**
* UI onclick listener to call jobFinished() in our service.
*/
public void finishJob(View v) {
if (!ensureTestService()) {
return;
}
mTestService.callJobFinished();
mParamsTextView.setText("");
}
/**
* Receives callback from the service when a job has landed
* on the app. Colours the UI and post a message to
* uncolour it after a second.
*/
public void onReceivedStartJob(JobParameters params) {
mShowStartView.setBackgroundColor(startJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
}
/**
* Receives callback from the service when a job that
* previously landed on the app must stop executing.
* Colours the UI and post a message to uncolour it after a
* second.
*/
public void onReceivedStopJob() {
mShowStopView.setBackgroundColor(stopJobColor);
Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
mParamsTextView.setText("");
}
}
然后新建一个类继承JobService
[java] view
plain copy
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.jobscheduler.service;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import com.example.android.jobscheduler.MainActivity;
import java.util.LinkedList;
/**
* Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler
* ultimately land on this service's "onStartJob" method. Currently all this does is post a message
* to the app's main activity to change the state of the UI.
*/
public class TestJobService extends JobService {
private static final String TAG = "SyncService";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service created");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroyed");
}
/**
* When the app's MainActivity is created, it starts this service. This is so that the
* activity and this service can communicate back and forth. See "setUiCalback()"
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Messenger callback = intent.getParcelableExtra("messenger");
Message m = Message.obtain();
m.what = MainActivity.MSG_SERVICE_OBJ;
m.obj = this;
try {
callback.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Error passing service object back to activity.");
}
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
// We don't do any real 'work' in this sample app. All we'll
// do is track which jobs have landed on our service, and
// update the UI accordingly.
jobParamsMap.add(params);
if (mActivity != null) {
mActivity.onReceivedStartJob(params);
}
Log.i(TAG, "on start job: " + params.getJobId());
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
// Stop tracking these job parameters, as we've 'finished' executing.
jobParamsMap.remove(params);
if (mActivity != null) {
mActivity.onReceivedStopJob();
}
Log.i(TAG, "on stop job: " + params.getJobId());
return true;
}
MainActivity mActivity;
private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
public void setUiCallback(MainActivity activity) {
mActivity = activity;
}
/** Send job to the JobScheduler. */
public void scheduleJob(JobInfo t) {
Log.d(TAG, "Scheduling job");
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(t);
}
/**
* Not currently used, but as an exercise you can hook this
* up to a button in the UI to finish a job that has landed
* in onStartJob().
*/
public boolean callJobFinished() {
JobParameters params = jobParamsMap.poll();
if (params == null) {
return false;
} else {
jobFinished(params, false);
return true;
}
}
}
具体详细代码可以参考下载的sdk里面
相关文章推荐
- android SeekBar的自定义样式设置
- Android中activity保存状态和数据到底该在哪个方法中进行
- Android的View绘制流程
- AndroidAnnotations框架的使用详解
- 关于Android 使用服务器公钥RSA加密 数据到服务器RSA解密报错问题
- android保存文件到sd卡,读取和清空记录功能(可以用来保存用户名和密码)
- Android项目中的欢迎界面和引导页:动画和ViewPager
- Android Handler机制分析
- Missing Gradle Project Information
- Android Studio简记
- Android ViewPager监听其控件
- Android使用ImageView 制作透明圆弧实例代码
- Android学习笔记八:SQLite判断一张表是否存在
- Android之注解IOC(二)
- Android接口回调深入理解
- 关于5.0以下Android状态栏背景色变换
- Android杂谈(5):ViewPager中Fragment跳转时出现界面无任何展示
- android学习笔记-数据存储File SharedPreference Sqlite
- android studio 引用Lisbs的.so文件
- Android内核开发:如何统计系统的启动时间