blob: 3e4c041367a09365e03559cc63e28ce1fdbceb10 [file] [log] [blame]
David Friedmanbf31c622016-03-03 13:55:00 -08001page.title=Background Optimizations
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -08002page.metaDescription=New restrictions to implicit broadcasts.
3page.keywords="android N", "implicit broadcasts", "job scheduler"
Dirk Dougherty9ae42db2016-05-15 18:52:24 -07004page.image=images/cards/card-nyc_2x.jpg
5
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -08006@jd:body
7
8<div id="qv-wrapper">
9 <div id="qv">
10 <h2>
11 In this document
12 </h2>
13
14 <ol>
15 <li>
16 <a href="#connectivity-action">Restrictions on CONNECTIVITY_ACTION</a>
17 </li>
18
19 <li>
20 <a href="#sched-jobs">Scheduling Network Jobs on Unmetered
21 Connections</a>
22 </li>
23
24 <li>
25 <a href="#monitor-conn">Monitoring Network Connectivity While the App
26 is Running</a>
27 </li>
28
29 <li>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080030 <a href="#media-broadcasts">Restrictions on NEW_PICTURE and
31 NEW_VIDEO</a>
32 </li>
33
34 <li>
35 <a href="#new-jobinfo">New JobInfo methods</a>
36 </li>
37
38 <li>
39 <a href="#new-jobparam">New JobParameter Methods</a>
40 </li>
41
42 <li>
43 <a href="#further-optimization">Further Optimizing Your App</a>
44 </li>
45 </ol>
46 </div>
47</div>
48
49<p>
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080050 Background processes can be memory- and battery-intensive. For example, an
51 implicit broadcast may start many background processes that have registered
52 to listen for it, even if those processes may not do much work. This can have
53 a substantial impact on both device performance and user experience.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080054</p>
55
56<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -070057 To alleviate this issue, Android N applies the following
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080058 restrictions:
59</p>
60
61<ul>
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080062 <li>Apps targeting the Preview do not receive {@link
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080063 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
Adarsh Fernando58cd6d42016-04-19 08:16:03 -070064 register to receive them in their manifest. Apps that are running can still
65 listen for {@code CONNECTIVITY_CHANGE} on their main thread by registering a
66 {@link android.content.BroadcastReceiver} with {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080067 android.content.Context#registerReceiver Context.registerReceiver()}.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080068 </li>
69
Adarsh Fernando37601562016-03-09 09:53:57 -080070 <li>Apps cannot send or receive {@link
71 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
72 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This optimization
73 affects all apps, not only those targeting the Preview.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080074 </li>
75</ul>
76
77<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -070078 If your app uses any of these intents, you should remove dependencies on
79 them as soon as possible so that you can target Android N devices properly.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080080 The Android framework provides several solutions to mitigate the need for
81 these implicit broadcasts. For example, {@link android.app.job.JobScheduler}
82 and <a href=
83 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080084 {@code GcmNetworkManager}</a> provide robust mechanisms to schedule network
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080085 operations when specified conditions, such as a connection to an unmetered
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080086 network, are met. You can now also use {@link android.app.job.JobScheduler}
87 to react to changes to content providers. {@link android.app.job.JobInfo}
88 objects encapsulate the parameters that {@link android.app.job.JobScheduler}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080089 uses to schedule your job. When the conditions of the job are met, the system
90 executes this job on your app's {@link android.app.job.JobService}.
91</p>
92
93<p>
94 In this document, we will learn how to use alternative methods, such as
95 {@link android.app.job.JobScheduler}, to adapt your app to these new
96 restrictions.
97</p>
98
99<h2 id="connectivity-action">
100 Restrictions on CONNECTIVITY_ACTION
101</h2>
102
103<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -0700104 Apps targeting the Android N do not receive {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800105 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
106 register to receive them in their manifest, and processes that depend on this
107 broadcast will not start. This could pose a problem for apps that want
108 to listen for network changes or perform bulk network activities when the
109 device connects to an unmetered network. Several solutions to get around this
110 restriction already exist in the Android framework, but choosing the right
111 one depends on what you want your app to accomplish.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800112</p>
113
114<p class="note">
115 <strong>Note:</strong> A {@link android.content.BroadcastReceiver} registered with
116 {@link android.content.Context#registerReceiver Context.registerReceiver()}
Adarsh Fernando9140e0d2016-04-06 10:36:53 -0700117 continues to receive these broadcasts while the app is running.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800118</p>
119
120<h3 id="sched-jobs">
121 Scheduling Network Jobs on Unmetered Connections
122</h3>
123
124<p>
125 When using the {@link android.app.job.JobInfo.Builder JobInfo.Builder} class
126 to build your {@link android.app.job.JobInfo} object, apply the {@link
127 android.app.job.JobInfo.Builder#setRequiredNetworkType
128 setRequiredNetworkType()} method and pass {@link android.app.job.JobInfo
129 JobInfo.NETWORK_TYPE_UNMETERED} as a job parameter. The following code sample
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800130 schedules a service to run when the device connects to an unmetered
131 network and is charging:
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800132</p>
133
134<pre>
135public static final int MY_BACKGROUND_JOB = 0;
136...
137public static void scheduleJob(Context context) {
138 JobScheduler js =
139 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
140 JobInfo job = new JobInfo.Builder(
141 MY_BACKGROUND_JOB,
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800142 new ComponentName(context, MyJobService.class))
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800143 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
144 .setRequiresCharging(true)
145 .build();
146 js.schedule(job);
147}
148</pre>
149
150<p>
151 When the conditions for your job are met, your app receives a callback to run
152 the {@link android.app.job.JobService#onStartJob onStartJob()} method in the
153 specified {@code JobService.class}. To see more examples of {@link
154 android.app.job.JobScheduler} implementation, see the <a href=
155 "{@docRoot}samples/JobScheduler/index.html">JobScheduler sample app</a>.
156</p>
157
158<p>
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800159 Applications that use GMSCore services, and target Android 5.0 (API level 21)
160 or lower, can use <a href=
161 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
162 {@code GcmNetworkManager}</a> and specify {@code Task.NETWORK_STATE_UNMETERED}.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800163</p>
164
165<h3 id="monitor-conn">
166 Monitoring Network Connectivity While the App is Running
167</h3>
168
169<p>
Adarsh Fernando58cd6d42016-04-19 08:16:03 -0700170 Apps that are running can still listen for {@code CONNECTIVITY_CHANGE} with a
171 registered {@link android.content.BroadcastReceiver}. However, the {@link
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800172 android.net.ConnectivityManager} API provides a more robust method to request
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800173 a callback only when specified network conditions are met.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800174</p>
175
176<p>
177 {@link android.net.NetworkRequest} objects define the parameters of the
178 network callback in terms of {@link android.net.NetworkCapabilities}. You
179 create {@link android.net.NetworkRequest} objects with the {@link
180 android.net.NetworkRequest.Builder NetworkRequest.Builder} class. {@link
181 android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest,
182 android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()}
183 then passes the {@link android.net.NetworkRequest} object to the system. When
184 the network conditions are met, the app receives a callback to execute the
185 {@link android.net.ConnectivityManager.NetworkCallback#onAvailable
186 onAvailable()} method defined in its {@link
187 android.net.ConnectivityManager.NetworkCallback} class.
188</p>
189
190<p>
191 The app continues to receive callbacks until either the app exits or it calls
192 {@link android.net.ConnectivityManager#unregisterNetworkCallback
193 unregisterNetworkCallback()}.
194</p>
195
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800196<h2 id="media-broadcasts">
197 Restrictions on NEW_PICTURE and NEW_VIDEO
198</h2>
199
200<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -0700201 In the Android N, apps are not able to send or receive {@link
Adarsh Fernando37601562016-03-09 09:53:57 -0800202 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
203 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This restriction helps
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800204 alleviate the performance and user experience impacts when several apps must
Dirk Dougherty51d90712016-03-15 15:47:36 -0700205 wake up in order to process a new image or video. Android N
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800206 extends {@link android.app.job.JobInfo} and {@link
207 android.app.job.JobParameters} to provide an alternative solution.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800208</p>
209
210<h3 id="new-jobinfo">
211 New JobInfo methods
212</h3>
213
214<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -0700215 To trigger jobs on content URI changes, Android N extends
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800216 the {@link android.app.job.JobInfo} API with the following methods:
217</p>
218
219<dl>
220 <dt>
221 {@code JobInfo.TriggerContentUri()}
222 </dt>
223
224 <dd>
225 Encapsulates parameters required to trigger a job on content URI changes.
226 </dd>
227
228 <dt>
229 {@code JobInfo.Builder.addTriggerContentUri()}
230 </dt>
231
232 <dd>
233 Passes a {@code TriggerContentUri} object to {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800234 android.app.job.JobInfo}. A {@link android.database.ContentObserver}
235 monitors the encapsulated content URI. If there are multiple {@code
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800236 TriggerContentUri} objects associated with a job, the system provides a
237 callback even if it reports a change in only one of the content URIs.
238 </dd>
239
240 <dd>
241 Add the {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} flag to
242 trigger the job if any descendants of the given URI change. This flag
243 corresponds to the {@code notifyForDescendants} parameter passed to {@link
244 android.content.ContentResolver#registerContentObserver
245 registerContentObserver()}.
246 </dd>
247</dl>
248
249<p class="note">
250 <strong>Note:</strong> {@code TriggerContentUri()} cannot be used in
251 combination with {@link android.app.job.JobInfo.Builder#setPeriodic
252 setPeriodic()} or {@link android.app.job.JobInfo.Builder#setPersisted
253 setPersisted()}. To continually monitor for content changes, schedule a new
254 {@link android.app.job.JobInfo} before the app’s {@link
255 android.app.job.JobService} finishes handling the most recent callback.
256</p>
257
258<p>
259 The following sample code schedules a job to trigger when the system reports
260 a change to the content URI, {@code MEDIA_URI}:
261</p>
262
263<pre>
264public static final int MY_BACKGROUND_JOB = 0;
265...
266public static void scheduleJob(Context context) {
267 JobScheduler js =
268 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
269 JobInfo.Builder builder = new JobInfo.Builder(
270 MY_BACKGROUND_JOB,
271 new ComponentName(context, MediaContentJob.class));
272 builder.addTriggerContentUri(
Adarsh Fernando9140e0d2016-04-06 10:36:53 -0700273 new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800274 JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
275 js.schedule(builder.build());
276}
277</pre>
278<p>
279 When the system reports a change in the specified content URI(s), your app
280 receives a callback and a {@link android.app.job.JobParameters} object is
281 passed to the {@link android.app.job.JobService#onStartJob onStartJob()}
282 method in {@code MediaContentJob.class}.
283</p>
284
285<h3 id="new-jobparam">
286 New JobParameter Methods
287</h3>
288
289<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -0700290 Android N also extends {@link android.app.job.JobParameters} to
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800291 allow your app to receive useful information about what content authorities
292 and URIs triggered the job:
293</p>
294
295<dl>
296 <dt>
297 {@code Uri[] getTriggeredContentUris()}
298 </dt>
299
300 <dd>
301 Returns an array of URIs that have triggered the job. This will be {@code
302 null} if either no URIs have triggered the job (for example, the job was
303 triggered due to a deadline or some other reason), or the number of changed
304 URIs is greater than 50.
305 </dd>
306
307 <dt>
308 {@code String[] getTriggeredContentAuthorities()}
309 </dt>
310
311 <dd>
312 Returns a string array of content authorities that have triggered the job.
313 If the returned array is not {@code null}, use {@code getTriggeredContentUris()}
314 to retrieve the details of which URIs have changed.
315 </dd>
316</dl>
317
318<p>
319 The following sample code overrides the {@link
320 android.app.job.JobService#onStartJob JobService.onStartJob()} method and
321 records the content authorities and URIs that have triggered the job:
322</p>
323
324<pre>
325&#64;Override
326public boolean onStartJob(JobParameters params) {
327 StringBuilder sb = new StringBuilder();
328 sb.append("Media content has changed:\n");
329 if (params.getTriggeredContentAuthorities() != null) {
330 sb.append("Authorities: ");
331 boolean first = true;
332 for (String auth :
333 params.getTriggeredContentAuthorities()) {
334 if (first) {
335 first = false;
336 } else {
337 sb.append(", ");
338 }
339 sb.append(auth);
340 }
341 if (params.getTriggeredContentUris() != null) {
342 for (Uri uri : params.getTriggeredContentUris()) {
343 sb.append("\n");
344 sb.append(uri);
345 }
346 }
347 } else {
348 sb.append("(No content)");
349 }
350 Log.i(TAG, sb.toString());
351 return true;
352}
353</pre>
354
355<h2 id="further-optimization">
356 Further Optimizing Your App
357</h2>
358
359<p>
360 Optimizing your apps to run on low-memory devices, or in low-memory
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800361 conditions, can improve performance and user experience. Removing
362 dependencies on background services and statically-registered implicit
363 broadcast receivers can help your app run better on such devices. Although
Dirk Dougherty51d90712016-03-15 15:47:36 -0700364 Android N takes steps to reduce some of these issues, it is
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800365 recommended that you optimize your app to run without the use of these
366 background processes entirely.
367</p>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800368
369<p>
Dirk Dougherty51d90712016-03-15 15:47:36 -0700370 Android N introduces some additional <a href=
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800371 "{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> commands that
372 you can use to test app behavior with those background processes disabled:
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800373</p>
374
375<ul>
376 <li>To simulate conditions where implicit broadcasts and background services
377 are unavailable, enter the following command:
378 </li>
379
380 <li style="list-style: none; display: inline">
381<pre class="no-pretty-print">
David Friedmanf3851c12016-07-20 13:44:10 -0700382{@code $ adb shell cmd appops set &lt;package_name&gt; RUN_IN_BACKGROUND ignore}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800383</pre>
384 </li>
385
386 <li>To re-enable implicit broadcasts and background services, enter the
387 following command:
388 </li>
389
390 <li style="list-style: none; display: inline">
391<pre class="no-pretty-print">
David Friedmanf3851c12016-07-20 13:44:10 -0700392{@code $ adb shell cmd appops set &lt;package_name&gt; RUN_IN_BACKGROUND allow}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800393</pre>
394 </li>
Hemal Patel593de1a2016-05-17 17:00:32 -0700395</ul>