1 page.title=Background Optimizations
2 page.metaDescription=New restrictions to implicit broadcasts.
3 page.keywords="android N", "implicit broadcasts", "job scheduler"
14 <a href="#connectivity-action">Restrictions on CONNECTIVITY_ACTION</a>
18 <a href="#sched-jobs">Scheduling Network Jobs on Unmetered
23 <a href="#monitor-conn">Monitoring Network Connectivity While the App
28 <a href="#media-broadcasts">Restrictions on NEW_PICTURE and
33 <a href="#new-jobinfo">New JobInfo methods</a>
37 <a href="#new-jobparam">New JobParameter Methods</a>
41 <a href="#further-optimization">Further Optimizing Your App</a>
48 Background processes can be memory- and battery-intensive. For example, an
49 implicit broadcast may start many background processes that have registered
50 to listen for it, even if those processes may not do much work. This can have
51 a substantial impact on both device performance and user experience.
55 To alleviate this issue, the N Developer Preview applies the following
60 <li>Apps targeting the Preview do not receive {@link
61 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
62 register to receive them in their manifest. Apps running in the foreground
63 can still listen for {@code CONNECTIVITY_CHANGE} on their main thread by
64 registering a {@link android.content.BroadcastReceiver} with {@link
65 android.content.Context#registerReceiver Context.registerReceiver()}.
68 <li>Apps cannot send or receive {@link
69 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
70 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This optimization
71 affects all apps, not only those targeting the Preview.
76 The Android framework provides several solutions to mitigate the need for
77 these implicit broadcasts. For example, {@link android.app.job.JobScheduler}
79 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
80 {@code GcmNetworkManager}</a> provide robust mechanisms to schedule network
81 operations when specified conditions, such as a connection to an unmetered
82 network, are met. You can now also use {@link android.app.job.JobScheduler}
83 to react to changes to content providers. {@link android.app.job.JobInfo}
84 objects encapsulate the parameters that {@link android.app.job.JobScheduler}
85 uses to schedule your job. When the conditions of the job are met, the system
86 executes this job on your app's {@link android.app.job.JobService}.
90 In this document, we will learn how to use alternative methods, such as
91 {@link android.app.job.JobScheduler}, to adapt your app to these new
95 <h2 id="connectivity-action">
96 Restrictions on CONNECTIVITY_ACTION
100 Apps targeting the N Developer Preview do not receive {@link
101 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
102 register to receive them in their manifest, and processes that depend on this
103 broadcast will not start. This could pose a problem for apps that want
104 to listen for network changes or perform bulk network activities when the
105 device connects to an unmetered network. Several solutions to get around this
106 restriction already exist in the Android framework, but choosing the right
107 one depends on what you want your app to accomplish.
111 <strong>Note:</strong> A {@link android.content.BroadcastReceiver} registered with
112 {@link android.content.Context#registerReceiver Context.registerReceiver()}
113 continues to receive these broadcasts while the app is in the foreground.
117 Scheduling Network Jobs on Unmetered Connections
121 When using the {@link android.app.job.JobInfo.Builder JobInfo.Builder} class
122 to build your {@link android.app.job.JobInfo} object, apply the {@link
123 android.app.job.JobInfo.Builder#setRequiredNetworkType
124 setRequiredNetworkType()} method and pass {@link android.app.job.JobInfo
125 JobInfo.NETWORK_TYPE_UNMETERED} as a job parameter. The following code sample
126 schedules a service to run when the device connects to an unmetered
127 network and is charging:
131 public static final int MY_BACKGROUND_JOB = 0;
133 public static void scheduleJob(Context context) {
135 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
136 JobInfo job = new JobInfo.Builder(
138 new ComponentName(context, MyJobService.class))
139 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
140 .setRequiresCharging(true)
147 When the conditions for your job are met, your app receives a callback to run
148 the {@link android.app.job.JobService#onStartJob onStartJob()} method in the
149 specified {@code JobService.class}. To see more examples of {@link
150 android.app.job.JobScheduler} implementation, see the <a href=
151 "{@docRoot}samples/JobScheduler/index.html">JobScheduler sample app</a>.
155 Applications that use GMSCore services, and target Android 5.0 (API level 21)
156 or lower, can use <a href=
157 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
158 {@code GcmNetworkManager}</a> and specify {@code Task.NETWORK_STATE_UNMETERED}.
161 <h3 id="monitor-conn">
162 Monitoring Network Connectivity While the App is Running
166 Apps running in the foreground can still listen for {@code
167 CONNECTIVITY_CHANGE} with a registered {@link
168 android.content.BroadcastReceiver}. However, the {@link
169 android.net.ConnectivityManager} API provides a more robust method to request
170 a callback only when specified network conditions are met.
174 {@link android.net.NetworkRequest} objects define the parameters of the
175 network callback in terms of {@link android.net.NetworkCapabilities}. You
176 create {@link android.net.NetworkRequest} objects with the {@link
177 android.net.NetworkRequest.Builder NetworkRequest.Builder} class. {@link
178 android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest,
179 android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()}
180 then passes the {@link android.net.NetworkRequest} object to the system. When
181 the network conditions are met, the app receives a callback to execute the
182 {@link android.net.ConnectivityManager.NetworkCallback#onAvailable
183 onAvailable()} method defined in its {@link
184 android.net.ConnectivityManager.NetworkCallback} class.
188 The app continues to receive callbacks until either the app exits or it calls
189 {@link android.net.ConnectivityManager#unregisterNetworkCallback
190 unregisterNetworkCallback()}.
193 <h2 id="media-broadcasts">
194 Restrictions on NEW_PICTURE and NEW_VIDEO
198 In the N Developer Preview, apps are not able to send or receive {@link
199 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
200 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This restriction helps
201 alleviate the performance and user experience impacts when several apps must
202 wake up in order to process a new image or video. The N Developer Preview
203 extends {@link android.app.job.JobInfo} and {@link
204 android.app.job.JobParameters} to provide an alternative solution.
207 <h3 id="new-jobinfo">
212 To trigger jobs on content URI changes, the N Developer Preview extends
213 the {@link android.app.job.JobInfo} API with the following methods:
218 {@code JobInfo.TriggerContentUri()}
222 Encapsulates parameters required to trigger a job on content URI changes.
226 {@code JobInfo.Builder.addTriggerContentUri()}
230 Passes a {@code TriggerContentUri} object to {@link
231 android.app.job.JobInfo}. A {@link android.database.ContentObserver}
232 monitors the encapsulated content URI. If there are multiple {@code
233 TriggerContentUri} objects associated with a job, the system provides a
234 callback even if it reports a change in only one of the content URIs.
238 Add the {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} flag to
239 trigger the job if any descendants of the given URI change. This flag
240 corresponds to the {@code notifyForDescendants} parameter passed to {@link
241 android.content.ContentResolver#registerContentObserver
242 registerContentObserver()}.
247 <strong>Note:</strong> {@code TriggerContentUri()} cannot be used in
248 combination with {@link android.app.job.JobInfo.Builder#setPeriodic
249 setPeriodic()} or {@link android.app.job.JobInfo.Builder#setPersisted
250 setPersisted()}. To continually monitor for content changes, schedule a new
251 {@link android.app.job.JobInfo} before the app’s {@link
252 android.app.job.JobService} finishes handling the most recent callback.
256 The following sample code schedules a job to trigger when the system reports
257 a change to the content URI, {@code MEDIA_URI}:
261 public static final int MY_BACKGROUND_JOB = 0;
263 public static void scheduleJob(Context context) {
265 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
266 JobInfo.Builder builder = new JobInfo.Builder(
268 new ComponentName(context, MediaContentJob.class));
269 builder.addTriggerContentUri(
270 new JobInfo.TriggerContentUri(MEDIA_URI,
271 JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
272 js.schedule(builder.build());
276 When the system reports a change in the specified content URI(s), your app
277 receives a callback and a {@link android.app.job.JobParameters} object is
278 passed to the {@link android.app.job.JobService#onStartJob onStartJob()}
279 method in {@code MediaContentJob.class}.
282 <h3 id="new-jobparam">
283 New JobParameter Methods
287 The N Developer Preview also extends {@link android.app.job.JobParameters} to
288 allow your app to receive useful information about what content authorities
289 and URIs triggered the job:
294 {@code Uri[] getTriggeredContentUris()}
298 Returns an array of URIs that have triggered the job. This will be {@code
299 null} if either no URIs have triggered the job (for example, the job was
300 triggered due to a deadline or some other reason), or the number of changed
301 URIs is greater than 50.
305 {@code String[] getTriggeredContentAuthorities()}
309 Returns a string array of content authorities that have triggered the job.
310 If the returned array is not {@code null}, use {@code getTriggeredContentUris()}
311 to retrieve the details of which URIs have changed.
316 The following sample code overrides the {@link
317 android.app.job.JobService#onStartJob JobService.onStartJob()} method and
318 records the content authorities and URIs that have triggered the job:
323 public boolean onStartJob(JobParameters params) {
324 StringBuilder sb = new StringBuilder();
325 sb.append("Media content has changed:\n");
326 if (params.getTriggeredContentAuthorities() != null) {
327 sb.append("Authorities: ");
328 boolean first = true;
330 params.getTriggeredContentAuthorities()) {
338 if (params.getTriggeredContentUris() != null) {
339 for (Uri uri : params.getTriggeredContentUris()) {
345 sb.append("(No content)");
347 Log.i(TAG, sb.toString());
352 <h2 id="further-optimization">
353 Further Optimizing Your App
357 Optimizing your apps to run on low-memory devices, or in low-memory
358 conditions, can improve performance and user experience. Removing
359 dependencies on background services and statically-registered implicit
360 broadcast receivers can help your app run better on such devices. Although
361 the N Developer Preview takes steps to reduce some of these issues, it is
362 recommended that you optimize your app to run without the use of these
363 background processes entirely.
367 The N Developer Preview introduces some additional <a href=
368 "{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> commands that
369 you can use to test app behavior with those background processes disabled:
373 <li>To simulate conditions where implicit broadcasts and background services
374 are unavailable, enter the following command:
377 <li style="list-style: none; display: inline">
378 <pre class="no-pretty-print">
379 {@code $ adb shell cmd appops set RUN_IN_BACKGROUND ignore}
383 <li>To re-enable implicit broadcasts and background services, enter the
387 <li style="list-style: none; display: inline">
388 <pre class="no-pretty-print">
389 {@code $ adb shell cmd appops set RUN_IN_BACKGROUND allow}