blob: 0a1a6f5336be57f9c172ec974cffef6643819065 [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>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070017 <ul>
18 <li>
19 <a href="#sched-jobs">Scheduling Network Jobs on Unmetered
20 Connections</a>
21 </li>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080022
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070023 <li>
24 <a href="#monitor-conn">Monitoring Network Connectivity While the
25 App is Running</a>
26 </li>
27 </ul>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080028 </li>
29
30 <li>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080031 <a href="#media-broadcasts">Restrictions on NEW_PICTURE and
32 NEW_VIDEO</a>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070033 <ul>
34 <li>
35 <a href="#new-jobinfo">New JobInfo methods</a>
36 </li>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080037
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070038 <li>
39 <a href="#new-jobparam">New JobParameter Methods</a>
40 </li>
41 </ul>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080042 </li>
43
44 <li>
45 <a href="#further-optimization">Further Optimizing Your App</a>
46 </li>
47 </ol>
48 </div>
49</div>
50
51<p>
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080052 Background processes can be memory- and battery-intensive. For example, an
53 implicit broadcast may start many background processes that have registered
54 to listen for it, even if those processes may not do much work. This can have
55 a substantial impact on both device performance and user experience.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080056</p>
57
58<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070059 To alleviate this issue, Android 7.0 (API level 24) applies the following
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080060 restrictions:
61</p>
62
63<ul>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070064 <li>Apps targeting Android 7.0 (API level 24) do not receive {@link
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080065 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
Adarsh Fernando58cd6d42016-04-19 08:16:03 -070066 register to receive them in their manifest. Apps that are running can still
67 listen for {@code CONNECTIVITY_CHANGE} on their main thread by registering a
68 {@link android.content.BroadcastReceiver} with {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080069 android.content.Context#registerReceiver Context.registerReceiver()}.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080070 </li>
71
Adarsh Fernando37601562016-03-09 09:53:57 -080072 <li>Apps cannot send or receive {@link
73 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
74 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This optimization
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070075 affects all apps, not only those targeting Android 7.0 (API level 24).
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080076 </li>
77</ul>
78
79<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -070080 If your app uses any of these intents, you should remove dependencies on them
81 as soon as possible so that you can target devices running Android 7.0
82 properly. The Android framework provides several solutions to mitigate the
83 need for these implicit broadcasts. For example, {@link
84 android.app.job.JobScheduler} and <a href=
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080085 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080086 {@code GcmNetworkManager}</a> provide robust mechanisms to schedule network
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080087 operations when specified conditions, such as a connection to an unmetered
Adarsh Fernando17de2cc2016-03-08 16:56:31 -080088 network, are met. You can now also use {@link android.app.job.JobScheduler}
89 to react to changes to content providers. {@link android.app.job.JobInfo}
90 objects encapsulate the parameters that {@link android.app.job.JobScheduler}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -080091 uses to schedule your job. When the conditions of the job are met, the system
92 executes this job on your app's {@link android.app.job.JobService}.
93</p>
94
95<p>
96 In this document, we will learn how to use alternative methods, such as
97 {@link android.app.job.JobScheduler}, to adapt your app to these new
98 restrictions.
99</p>
100
101<h2 id="connectivity-action">
102 Restrictions on CONNECTIVITY_ACTION
103</h2>
104
105<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700106 Apps targeting Android 7.0 (API level 24) do not receive {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800107 android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts if they
108 register to receive them in their manifest, and processes that depend on this
109 broadcast will not start. This could pose a problem for apps that want
110 to listen for network changes or perform bulk network activities when the
111 device connects to an unmetered network. Several solutions to get around this
112 restriction already exist in the Android framework, but choosing the right
113 one depends on what you want your app to accomplish.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800114</p>
115
116<p class="note">
117 <strong>Note:</strong> A {@link android.content.BroadcastReceiver} registered with
118 {@link android.content.Context#registerReceiver Context.registerReceiver()}
Adarsh Fernando9140e0d2016-04-06 10:36:53 -0700119 continues to receive these broadcasts while the app is running.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800120</p>
121
122<h3 id="sched-jobs">
123 Scheduling Network Jobs on Unmetered Connections
124</h3>
125
126<p>
127 When using the {@link android.app.job.JobInfo.Builder JobInfo.Builder} class
128 to build your {@link android.app.job.JobInfo} object, apply the {@link
129 android.app.job.JobInfo.Builder#setRequiredNetworkType
130 setRequiredNetworkType()} method and pass {@link android.app.job.JobInfo
131 JobInfo.NETWORK_TYPE_UNMETERED} as a job parameter. The following code sample
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800132 schedules a service to run when the device connects to an unmetered
133 network and is charging:
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800134</p>
135
136<pre>
137public static final int MY_BACKGROUND_JOB = 0;
138...
139public static void scheduleJob(Context context) {
140 JobScheduler js =
141 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
142 JobInfo job = new JobInfo.Builder(
143 MY_BACKGROUND_JOB,
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800144 new ComponentName(context, MyJobService.class))
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800145 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
146 .setRequiresCharging(true)
147 .build();
148 js.schedule(job);
149}
150</pre>
151
152<p>
153 When the conditions for your job are met, your app receives a callback to run
154 the {@link android.app.job.JobService#onStartJob onStartJob()} method in the
155 specified {@code JobService.class}. To see more examples of {@link
156 android.app.job.JobScheduler} implementation, see the <a href=
157 "{@docRoot}samples/JobScheduler/index.html">JobScheduler sample app</a>.
158</p>
159
160<p>
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800161 Applications that use GMSCore services, and target Android 5.0 (API level 21)
162 or lower, can use <a href=
163 "https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
164 {@code GcmNetworkManager}</a> and specify {@code Task.NETWORK_STATE_UNMETERED}.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800165</p>
166
167<h3 id="monitor-conn">
168 Monitoring Network Connectivity While the App is Running
169</h3>
170
171<p>
Adarsh Fernando58cd6d42016-04-19 08:16:03 -0700172 Apps that are running can still listen for {@code CONNECTIVITY_CHANGE} with a
173 registered {@link android.content.BroadcastReceiver}. However, the {@link
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800174 android.net.ConnectivityManager} API provides a more robust method to request
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800175 a callback only when specified network conditions are met.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800176</p>
177
178<p>
179 {@link android.net.NetworkRequest} objects define the parameters of the
180 network callback in terms of {@link android.net.NetworkCapabilities}. You
181 create {@link android.net.NetworkRequest} objects with the {@link
182 android.net.NetworkRequest.Builder NetworkRequest.Builder} class. {@link
183 android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest,
184 android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()}
185 then passes the {@link android.net.NetworkRequest} object to the system. When
186 the network conditions are met, the app receives a callback to execute the
187 {@link android.net.ConnectivityManager.NetworkCallback#onAvailable
188 onAvailable()} method defined in its {@link
189 android.net.ConnectivityManager.NetworkCallback} class.
190</p>
191
192<p>
193 The app continues to receive callbacks until either the app exits or it calls
194 {@link android.net.ConnectivityManager#unregisterNetworkCallback
195 unregisterNetworkCallback()}.
196</p>
197
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800198<h2 id="media-broadcasts">
199 Restrictions on NEW_PICTURE and NEW_VIDEO
200</h2>
201
202<p>
Adarsh Fernando9af57aa2016-09-21 15:45:04 -0700203 In Android 7.0 (API level 24), apps are not able to send or receive {@link
Adarsh Fernando37601562016-03-09 09:53:57 -0800204 android.hardware.Camera#ACTION_NEW_PICTURE} or {@link
205 android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This restriction helps
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800206 alleviate the performance and user experience impacts when several apps must
Adarsh Fernando9af57aa2016-09-21 15:45:04 -0700207 wake up in order to process a new image or video. Android 7.0 (API level 24)
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800208 extends {@link android.app.job.JobInfo} and {@link
209 android.app.job.JobParameters} to provide an alternative solution.
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800210</p>
211
212<h3 id="new-jobinfo">
213 New JobInfo methods
214</h3>
215
216<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700217 To trigger jobs on content URI changes, Android 7.0 (API level 24) extends
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800218 the {@link android.app.job.JobInfo} API with the following methods:
219</p>
220
221<dl>
222 <dt>
223 {@code JobInfo.TriggerContentUri()}
224 </dt>
225
226 <dd>
227 Encapsulates parameters required to trigger a job on content URI changes.
228 </dd>
229
230 <dt>
231 {@code JobInfo.Builder.addTriggerContentUri()}
232 </dt>
233
234 <dd>
235 Passes a {@code TriggerContentUri} object to {@link
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800236 android.app.job.JobInfo}. A {@link android.database.ContentObserver}
237 monitors the encapsulated content URI. If there are multiple {@code
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800238 TriggerContentUri} objects associated with a job, the system provides a
239 callback even if it reports a change in only one of the content URIs.
240 </dd>
241
242 <dd>
243 Add the {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} flag to
244 trigger the job if any descendants of the given URI change. This flag
245 corresponds to the {@code notifyForDescendants} parameter passed to {@link
246 android.content.ContentResolver#registerContentObserver
247 registerContentObserver()}.
248 </dd>
249</dl>
250
251<p class="note">
252 <strong>Note:</strong> {@code TriggerContentUri()} cannot be used in
253 combination with {@link android.app.job.JobInfo.Builder#setPeriodic
254 setPeriodic()} or {@link android.app.job.JobInfo.Builder#setPersisted
255 setPersisted()}. To continually monitor for content changes, schedule a new
256 {@link android.app.job.JobInfo} before the app’s {@link
257 android.app.job.JobService} finishes handling the most recent callback.
258</p>
259
260<p>
261 The following sample code schedules a job to trigger when the system reports
262 a change to the content URI, {@code MEDIA_URI}:
263</p>
264
265<pre>
266public static final int MY_BACKGROUND_JOB = 0;
267...
268public static void scheduleJob(Context context) {
269 JobScheduler js =
270 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
271 JobInfo.Builder builder = new JobInfo.Builder(
272 MY_BACKGROUND_JOB,
273 new ComponentName(context, MediaContentJob.class));
274 builder.addTriggerContentUri(
Adarsh Fernando9140e0d2016-04-06 10:36:53 -0700275 new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800276 JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
277 js.schedule(builder.build());
278}
279</pre>
280<p>
281 When the system reports a change in the specified content URI(s), your app
282 receives a callback and a {@link android.app.job.JobParameters} object is
283 passed to the {@link android.app.job.JobService#onStartJob onStartJob()}
284 method in {@code MediaContentJob.class}.
285</p>
286
287<h3 id="new-jobparam">
288 New JobParameter Methods
289</h3>
290
291<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700292 Android 7.0 (API level 24) also extends {@link android.app.job.JobParameters} to
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800293 allow your app to receive useful information about what content authorities
294 and URIs triggered the job:
295</p>
296
297<dl>
298 <dt>
299 {@code Uri[] getTriggeredContentUris()}
300 </dt>
301
302 <dd>
303 Returns an array of URIs that have triggered the job. This will be {@code
304 null} if either no URIs have triggered the job (for example, the job was
305 triggered due to a deadline or some other reason), or the number of changed
306 URIs is greater than 50.
307 </dd>
308
309 <dt>
310 {@code String[] getTriggeredContentAuthorities()}
311 </dt>
312
313 <dd>
314 Returns a string array of content authorities that have triggered the job.
315 If the returned array is not {@code null}, use {@code getTriggeredContentUris()}
316 to retrieve the details of which URIs have changed.
317 </dd>
318</dl>
319
320<p>
321 The following sample code overrides the {@link
322 android.app.job.JobService#onStartJob JobService.onStartJob()} method and
323 records the content authorities and URIs that have triggered the job:
324</p>
325
326<pre>
327&#64;Override
328public boolean onStartJob(JobParameters params) {
329 StringBuilder sb = new StringBuilder();
330 sb.append("Media content has changed:\n");
331 if (params.getTriggeredContentAuthorities() != null) {
332 sb.append("Authorities: ");
333 boolean first = true;
334 for (String auth :
335 params.getTriggeredContentAuthorities()) {
336 if (first) {
337 first = false;
338 } else {
339 sb.append(", ");
340 }
341 sb.append(auth);
342 }
343 if (params.getTriggeredContentUris() != null) {
344 for (Uri uri : params.getTriggeredContentUris()) {
345 sb.append("\n");
346 sb.append(uri);
347 }
348 }
349 } else {
350 sb.append("(No content)");
351 }
352 Log.i(TAG, sb.toString());
353 return true;
354}
355</pre>
356
357<h2 id="further-optimization">
358 Further Optimizing Your App
359</h2>
360
361<p>
362 Optimizing your apps to run on low-memory devices, or in low-memory
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800363 conditions, can improve performance and user experience. Removing
364 dependencies on background services and statically-registered implicit
365 broadcast receivers can help your app run better on such devices. Although
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700366 Android 7.0 (API level 24) takes steps to reduce some of these issues, it is
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800367 recommended that you optimize your app to run without the use of these
368 background processes entirely.
369</p>
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800370
371<p>
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700372 Android 7.0 (API level 24) introduces some additional <a href=
Adarsh Fernando17de2cc2016-03-08 16:56:31 -0800373 "{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> commands that
374 you can use to test app behavior with those background processes disabled:
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800375</p>
376
377<ul>
378 <li>To simulate conditions where implicit broadcasts and background services
379 are unavailable, enter the following command:
380 </li>
381
382 <li style="list-style: none; display: inline">
383<pre class="no-pretty-print">
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700384{@code $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800385</pre>
386 </li>
387
388 <li>To re-enable implicit broadcasts and background services, enter the
389 following command:
390 </li>
391
392 <li style="list-style: none; display: inline">
393<pre class="no-pretty-print">
Adarsh Fernando4b6d9392016-09-21 13:56:37 -0700394{@code $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow}
Adarsh Fernando9f2ab4f2016-02-24 19:07:10 -0800395</pre>
396 </li>
Hemal Patel593de1a2016-05-17 17:00:32 -0700397</ul>