Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: components/background_task_scheduler/README.md

Issue 2714463002: [android] Add JobScheduler-based BackgroundTaskScheduler. (Closed)
Patch Set: FindBugs wants the real Pi, but I won't give it. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/background_task_scheduler/README.md
diff --git a/components/background_task_scheduler/README.md b/components/background_task_scheduler/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c48720d51da763635ed4f85e66309881fc9d29e1
--- /dev/null
+++ b/components/background_task_scheduler/README.md
@@ -0,0 +1,163 @@
+# Quick Start Guide to using BackgroundTaskScheduler
+
+## Background
+
+In Android M+ it is encouraged to use `JobScheduler` for all background jobs,
+instead of using things like `IntentService` or polling using alarms. Using the
+system API is beneficial as it has a full view of what goes on in the system and
+can schedule jobs accordingly.
+
+However, this functionality was introduced in Android L, and
+the API has been very stable since Android M. This means that we also need a
+similar framework for older versions of Android, which is provided by
+Google Play services. We prefer system APIs, since they do not require including
+external libraries which bloats the APK size of Chrome and adds unnecessary
+complexity. The GcmNetworkManager is only used when the system API is not
+available.
+
+The `background_task_scheduler` component provides a new framework for use
+within chromium to schedule and execute background jobs using the frameworks
+available on a given version of Android.
+The public API of the framework is similar to that of the Android
+`JobScheduler`, but it is backed by either the system `JobScheduler` API or by
+GcmNetworkManager. What service is used to back the framework remains unknown to
+callers of the API.
+
+## What is a task
+
+A task is defined as a class that implements the `BackgroundTask` interface,
+which looks like this:
+
+```java
+interface BackgroundTask {
+ interface TaskFinishedCallback {
+ void taskFinished(boolean needsReschedule);
+ }
+
+ boolean onStartTask(Context context,
+ TaskParameters taskParameters,
+ TaskFinishedCallback callback);
+ boolean onStopTask(Context context,
+ TaskParameters taskParameters);
+}
+```
+
+**Any class implementing this interface must have a public constructor which takes
+no arguments.**
+
+A task must also have a unique ID, and it must be listed in `TaskIds` to ensure
+there is no overlap between different tasks.
+
+## How to schedule a task
+
+A task is scheduled by creating an object containing information about the task,
+such as when to run it, whether it requires battery, and other similar
+constraints. This object is called `TaskInfo` and has a builder you can use
+to set all the relevant fields.
+
+There are two main types of tasks; one-off tasks and periodic tasks. One-off
+tasks are only executed once, whereas periodic tasks are executed once per
+a defined interval.
+
+As an example for how to create a one-off task that executes in 200 minutes,
+you can do the following:
+
+```java
+TaskInfo.createOneOffTask(TaskIds.YOUR_FEATURE,
+ MyBackgroundTask.class,
+ TimeUnit.MINUTES.toMillis(200)).build();
+```
+
+For a periodic task that executes every 200 minutes, you can call:
+
+```java
+TaskInfo.createPeriodicTask(TaskIds.YOUR_FEATURE,
+ MyBackgroundTask.class,
+ TimeUnit.MINUTES.toMillis(200)).build();
+```
+
+Typically you will also set other required parameters such as what type of
+network conditions are necessary and whether the task requires the device to
+be charging. They can be set on the builder like this:
+
+```java
+TaskInfo.createOneOffTask(TaskIds.YOUR_FEATURE,
+ MyBackgroundTask.class,
+ TimeUnit.MINUTES.toMillis(100)
+ TimeUnit.MINUTES.toMillis(200))
+ .setRequiresCharging(true)
+ .setRequiredNetworkType(TaskInfo.NETWORK_TYPE_UNMETERED)
+ .build();
+```
+
+When the task is ready for scheduling, you use the
+`BackgroundTaskSchedulerFactory` to get the current instance of the
+`BackgroundTaskScheduler` and use it to schedule the job.
+
+```java
+BackgroundTaskScheduleFactory.getScheduler().schedule(myTaskInfo);
+```
+
+If you ever need to cancel a task, you can do that by calling `cancel`, and
+passing in the task ID:
+
+```java
+BackgroundTaskScheduleFactory.getScheduler().cancel(TaskIds.YOUR_FEATURE);
+```
+
+## Passing task arguments
+
+A `TaskInfo` supports passing in arguments through a `Bundle`, but only values
+that can be part of an Android `BaseBundle` are allowed. You can pass them in
+using the `TaskInfo.Builder`:
+
+```java
+Bundle myBundle = new Bundle();
+myBundle.putString("foo", "bar");
+myBundle.putLong("number", 1337L);
+
+TaskInfo.createOneOffTask(TaskIds.YOUR_FEATURE,
+ MyBackgroundTask.class,
+ TimeUnit.MINUTES.toMillis(100)
+ TimeUnit.MINUTES.toMillis(200))
+ .setExtras(myBundle)
+ .build();
+```
+
+These arguments will be readable for the task through the `TaskParameters`
+object that is passed to both `onStartTask(...)` and `onStopTask(...)`, by
+doing the following:
+
+```java
+boolean onStartTask(Context context,
+ TaskParameters taskParameters,
+ TaskFinishedCallback callback) {
+ Bundle myExtras = taskParameters.getExtras();
+ // Use |myExtras|.
+ ...
+}
+```
+
+## Background processing
+
+Even though the `BackgroundTaskScheduler` provides functionality for invoking
+code while the application is in the background, the `BackgroundTask` instance
+is still invoked on the application main thread.
+
+This means that unless the operation is extremely quick, processing must happen
+asynchronously, and the call to `onStartJob(...)` must return before the task
+has finished processing. In that case, `onStartJob(...)` must return true, and
+instead invoke the `TaskFinishedCallback` when the processing is finished, which
+typically happens on a different `Thread`, `Handler` or using an `AsyncTask`.
+
+If the task finishes while still being on the main thread, `onStartJob(...)`
+should return false, indicating that no further processsing is required.
+
+If at any time the constraints given through the `TaskInfo` object does not
+hold anymore, or if the system deems it necessary, `onStopTask(...)` will be
+invoked, requiring all activity to cease immediately. The task can return true
+if the task needs to be rescheduled since it was canceled, or false otherwise.
+
+**The system will hold a wakelock from the time `onStartTask(...)` is invoked
+until either the task itself invokes the `TaskFinishedCallback`, or
+`onStopTask(...)` is invoked.**

Powered by Google App Engine
This is Rietveld 408576698