Add sample for enqueuing work in a job.
am: 5229a90146
Change-Id: Idc0461e19fd7e14e2a41940b0db8a64f995d6db2
This commit is contained in:
@@ -595,6 +595,18 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".app.JobWorkService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"/>
|
||||
|
||||
<activity android:name=".app.JobWorkServiceActivity"
|
||||
android:label="@string/activity_job_work_service"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".app.ForegroundService" />
|
||||
<service android:name=".app.ForegroundService2" />
|
||||
|
||||
|
||||
53
samples/ApiDemos/res/layout/job_work_service_activity.xml
Normal file
53
samples/ApiDemos/res/layout/job_work_service_activity.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<!-- Demonstrates enqueueing work into a job.
|
||||
See corresponding Java code com.android.sdk.app.JobWorkServiceActivity.java. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:padding="4dip"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="0" android:paddingBottom="4dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="@string/job_work_service_controller"/>
|
||||
|
||||
<Button android:id="@+id/enqueue1"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/enqueue1_job">
|
||||
<requestFocus />
|
||||
</Button>
|
||||
|
||||
<Button android:id="@+id/enqueue2"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/enqueue2_job">
|
||||
</Button>
|
||||
|
||||
<Button android:id="@+id/enqueue3"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/enqueue3_job">
|
||||
</Button>
|
||||
|
||||
<Button android:id="@+id/kill"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/kill_process">
|
||||
</Button>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -302,6 +302,19 @@
|
||||
<string name="service_created">Service created.</string>
|
||||
<string name="service_destroyed">Service destroyed.</string>
|
||||
|
||||
<string name="job_work_service_label">Job Work Service</string>
|
||||
|
||||
<string name="activity_job_work_service">App/Job/Job Work Service Controller</string>
|
||||
<string name="job_work_service_controller">This demonstrates how
|
||||
work can be enqueued and executed by a job, running work in the job until
|
||||
everything is complete.
|
||||
</string>
|
||||
<string name="enqueue1_job">Enqueue \"One\"</string>
|
||||
<string name="enqueue2_job">Enqueue \"Two\"</string>
|
||||
<string name="enqueue3_job">Enqueue \"Three\"</string>
|
||||
<string name="job_service_created">JobService created.</string>
|
||||
<string name="job_service_destroyed">JobService destroyed.</string>
|
||||
|
||||
<string name="foreground_service_started">Service is in the foreground</string>
|
||||
<string name="foreground_service_label">Sample Foreground Service</string>
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.apis.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobService;
|
||||
import android.app.job.JobWorkItem;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
/**
|
||||
* This is an example of implementing a {@link JobService} that dispatches work enqueued in
|
||||
* to it. The {@link JobWorkServiceActivity} class shows how to interact with the service.
|
||||
*/
|
||||
//BEGIN_INCLUDE(service)
|
||||
public class JobWorkService extends JobService {
|
||||
private NotificationManager mNM;
|
||||
private CommandProcessor mCurProcessor;
|
||||
|
||||
/**
|
||||
* This is a task to dequeue and process work in the background.
|
||||
*/
|
||||
final class CommandProcessor extends AsyncTask<Void, Void, Void> {
|
||||
private final JobParameters mParams;
|
||||
|
||||
CommandProcessor(JobParameters params) {
|
||||
mParams = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
boolean cancelled;
|
||||
JobWorkItem work;
|
||||
|
||||
/**
|
||||
* Iterate over available work. Once dequeueWork() returns null, the
|
||||
* job's work queue is empty and the job has stopped, so we can let this
|
||||
* async task complete.
|
||||
*/
|
||||
while (!(cancelled=isCancelled()) && (work=mParams.dequeueWork()) != null) {
|
||||
String txt = work.getIntent().getStringExtra("name");
|
||||
Log.i("JobWorkService", "Processing work: " + work + ", msg: " + txt);
|
||||
showNotification(txt);
|
||||
|
||||
// Process work here... we'll pretend by sleeping.
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
hideNotification();
|
||||
|
||||
// Tell system we have finished processing the work.
|
||||
Log.i("JobWorkService", "Done with: " + work);
|
||||
mParams.completeWork(work);
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
Log.i("JobWorkService", "CANCELLED!");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
Toast.makeText(this, R.string.service_created, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
hideNotification();
|
||||
Toast.makeText(this, R.string.service_destroyed, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
// Start task to pull work out of the queue and process it.
|
||||
mCurProcessor = new CommandProcessor(params);
|
||||
mCurProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
// Allow the job to continue running while we process work.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
// Have the processor cancel its current work.
|
||||
mCurProcessor.cancel(true);
|
||||
|
||||
// Tell the system to reschedule the job -- the only reason we would be here is
|
||||
// because the job needs to stop for some reason before it has completed all of
|
||||
// its work, so we would like it to remain to finish that work in the future.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a notification while this service is running.
|
||||
*/
|
||||
private void showNotification(String text) {
|
||||
// The PendingIntent to launch our activity if the user selects this notification
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
|
||||
new Intent(this, JobWorkServiceActivity.class), 0);
|
||||
|
||||
// Set the info for the views that show in the notification panel.
|
||||
Notification.Builder noteBuilder = new Notification.Builder(this)
|
||||
.setSmallIcon(R.drawable.stat_sample) // the status icon
|
||||
.setTicker(text) // the status text
|
||||
.setWhen(System.currentTimeMillis()) // the time stamp
|
||||
.setContentTitle(getText(R.string.service_start_arguments_label)) // the label
|
||||
.setContentText(text) // the contents of the entry
|
||||
.setContentIntent(contentIntent); // The intent to send when the entry is clicked
|
||||
|
||||
// We show this for as long as our service is processing a command.
|
||||
noteBuilder.setOngoing(true);
|
||||
|
||||
// Send the notification.
|
||||
// We use a string id because it is a unique number. We use it later to cancel.
|
||||
mNM.notify(R.string.job_service_created, noteBuilder.build());
|
||||
}
|
||||
|
||||
private void hideNotification() {
|
||||
mNM.cancel(R.string.service_created);
|
||||
}
|
||||
}
|
||||
//END_INCLUDE(service)
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.apis.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.app.job.JobWorkItem;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.example.android.apis.R;
|
||||
|
||||
/**
|
||||
* Example of interacting with {@link JobWorkService}.
|
||||
*/
|
||||
public class JobWorkServiceActivity extends Activity {
|
||||
JobScheduler mJobScheduler;
|
||||
JobInfo mJobInfo;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mJobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
|
||||
mJobInfo = new JobInfo.Builder(R.string.job_service_created,
|
||||
new ComponentName(this, JobWorkService.class)).setOverrideDeadline(0).build();
|
||||
|
||||
setContentView(R.layout.job_work_service_activity);
|
||||
|
||||
// Watch for button clicks.
|
||||
Button button = findViewById(R.id.enqueue1);
|
||||
button.setOnClickListener(mEnqueue1Listener);
|
||||
button = findViewById(R.id.enqueue2);
|
||||
button.setOnClickListener(mEnqueue2Listener);
|
||||
button = findViewById(R.id.enqueue3);
|
||||
button.setOnClickListener(mEnqueue3Listener);
|
||||
button = findViewById(R.id.kill);
|
||||
button.setOnClickListener(mKillListener);
|
||||
}
|
||||
|
||||
private View.OnClickListener mEnqueue1Listener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mJobScheduler.enqueue(mJobInfo, new JobWorkItem(
|
||||
new Intent("com.example.android.apis.ONE").putExtra("name", "One")));
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener mEnqueue2Listener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mJobScheduler.enqueue(mJobInfo, new JobWorkItem(
|
||||
new Intent("com.example.android.apis.TWO").putExtra("name", "Two")));
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener mEnqueue3Listener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mJobScheduler.enqueue(mJobInfo, new JobWorkItem(
|
||||
new Intent("com.example.android.apis.THREE").putExtra("name", "Three")));
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener mKillListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
// This is to simulate the service being killed while it is
|
||||
// running in the background.
|
||||
Process.killProcess(Process.myPid());
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user