OSDN Git Service

4bcf78552563f4ae4c4124b9791052317986b30b
[android-x86/frameworks-base.git] / docs / html / preview / features / background-optimization.jd
1 page.title=Background Optimizations
2 page.metaDescription=New restrictions to implicit broadcasts.
3 page.keywords="android N", "implicit broadcasts", "job scheduler"
4 @jd:body
5
6 <div id="qv-wrapper">
7   <div id="qv">
8     <h2>
9       In this document
10     </h2>
11
12     <ol>
13       <li>
14         <a href="#connectivity-action">Restrictions on CONNECTIVITY_ACTION</a>
15       </li>
16
17       <li>
18         <a href="#sched-jobs">Scheduling Network Jobs on Unmetered
19         Connections</a>
20       </li>
21
22       <li>
23         <a href="#monitor-conn">Monitoring Network Connectivity While the App
24         is Running</a>
25       </li>
26
27       <li>
28         <a href="#media-broadcasts">Restrictions on NEW_PICTURE and
29         NEW_VIDEO</a>
30       </li>
31
32       <li>
33         <a href="#new-jobinfo">New JobInfo methods</a>
34       </li>
35
36       <li>
37         <a href="#new-jobparam">New JobParameter Methods</a>
38       </li>
39
40       <li>
41         <a href="#further-optimization">Further Optimizing Your App</a>
42       </li>
43     </ol>
44   </div>
45 </div>
46
47 <p>
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.
52 </p>
53
54 <p>
55   To alleviate this issue, the N Developer Preview applies the following
56   restrictions:
57 </p>
58
59 <ul>
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()}.
66   </li>
67
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.
72   </li>
73 </ul>
74
75 <p>
76   The Android framework provides several solutions to mitigate the need for
77   these implicit broadcasts. For example, {@link android.app.job.JobScheduler}
78   and <a href=
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}.
87 </p>
88
89 <p>
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
92   restrictions.
93 </p>
94
95 <h2 id="connectivity-action">
96   Restrictions on CONNECTIVITY_ACTION
97 </h2>
98
99 <p>
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.
108 </p>
109
110 <p class="note">
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.
114 </p>
115
116 <h3 id="sched-jobs">
117   Scheduling Network Jobs on Unmetered Connections
118 </h3>
119
120 <p>
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:
128 </p>
129
130 <pre>
131 public static final int MY_BACKGROUND_JOB = 0;
132 ...
133 public static void scheduleJob(Context context) {
134   JobScheduler js =
135       (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
136   JobInfo job = new JobInfo.Builder(
137     MY_BACKGROUND_JOB,
138     new ComponentName(context, MyJobService.class))
139       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
140       .setRequiresCharging(true)
141       .build();
142   js.schedule(job);
143 }
144 </pre>
145
146 <p>
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>.
152 </p>
153
154 <p>
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}.
159 </p>
160
161 <h3 id="monitor-conn">
162   Monitoring Network Connectivity While the App is Running
163 </h3>
164
165 <p>
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.
171 </p>
172
173 <p>
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.
185 </p>
186
187 <p>
188   The app continues to receive callbacks until either the app exits or it calls
189   {@link android.net.ConnectivityManager#unregisterNetworkCallback
190   unregisterNetworkCallback()}.
191 </p>
192
193 <h2 id="media-broadcasts">
194   Restrictions on NEW_PICTURE and NEW_VIDEO
195 </h2>
196
197 <p>
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.
205 </p>
206
207 <h3 id="new-jobinfo">
208   New JobInfo methods
209 </h3>
210
211 <p>
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:
214 </p>
215
216 <dl>
217   <dt>
218     {@code JobInfo.TriggerContentUri()}
219   </dt>
220
221   <dd>
222     Encapsulates parameters required to trigger a job on content URI changes.
223   </dd>
224
225   <dt>
226     {@code JobInfo.Builder.addTriggerContentUri()}
227   </dt>
228
229   <dd>
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.
235   </dd>
236
237   <dd>
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()}.
243   </dd>
244 </dl>
245
246 <p class="note">
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.
253 </p>
254
255 <p>
256   The following sample code schedules a job to trigger when the system reports
257   a change to the content URI, {@code MEDIA_URI}:
258 </p>
259
260 <pre>
261 public static final int MY_BACKGROUND_JOB = 0;
262 ...
263 public static void scheduleJob(Context context) {
264   JobScheduler js =
265           (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
266   JobInfo.Builder builder = new JobInfo.Builder(
267           MY_BACKGROUND_JOB,
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());
273 }
274 </pre>
275 <p>
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}.
280 </p>
281
282 <h3 id="new-jobparam">
283   New JobParameter Methods
284 </h3>
285
286 <p>
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:
290 </p>
291
292 <dl>
293   <dt>
294     {@code Uri[] getTriggeredContentUris()}
295   </dt>
296
297   <dd>
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.
302   </dd>
303
304   <dt>
305     {@code String[] getTriggeredContentAuthorities()}
306   </dt>
307
308   <dd>
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.
312   </dd>
313 </dl>
314
315 <p>
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:
319 </p>
320
321 <pre>
322 &#64;Override
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;
329       for (String auth :
330           params.getTriggeredContentAuthorities()) {
331           if (first) {
332               first = false;
333           } else {
334              sb.append(", ");
335           }
336            sb.append(auth);
337       }
338       if (params.getTriggeredContentUris() != null) {
339           for (Uri uri : params.getTriggeredContentUris()) {
340               sb.append("\n");
341               sb.append(uri);
342           }
343       }
344   } else {
345       sb.append("(No content)");
346   }
347   Log.i(TAG, sb.toString());
348   return true;
349 }
350 </pre>
351
352 <h2 id="further-optimization">
353   Further Optimizing Your App
354 </h2>
355
356 <p>
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.
364 </p>
365
366 <p>
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:
370 </p>
371
372 <ul>
373   <li>To simulate conditions where implicit broadcasts and background services
374   are unavailable, enter the following command:
375   </li>
376
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}
380 </pre>
381   </li>
382
383   <li>To re-enable implicit broadcasts and background services, enter the
384   following command:
385   </li>
386
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}
390 </pre>
391   </li>
392 </ul>