1page.title=Optimalisasi Latar Belakang
2page.metaDescription=Pembatasan baru pada siaran implisit.
3page.keywords="android N", "implicit broadcasts", "job scheduler"
4page.image=images/cards/card-nyc_2x.jpg
5
6@jd:body
7
8<div id="qv-wrapper">
9  <div id="qv">
10    <h2>
11      Dalam dokumen ini
12    </h2>
13
14    <ol>
15      <li>
16        <a href="#connectivity-action">Pembatasan pada CONNECTIVITY_ACTION</a>
17      </li>
18
19      <li>
20        <a href="#sched-jobs">Menjadwalkan Pekerjaan Jaringan pada Koneksi
21        Berbiaya Tetap</a>
22      </li>
23
24      <li>
25        <a href="#monitor-conn">Memantau Konektivitas Jaringan Saat Aplikasi
26        Dijalankan</a>
27      </li>
28
29      <li>
30        <a href="#media-broadcasts">Pembatasan pada NEW_PICTURE dan
31        NEW_VIDEO</a>
32      </li>
33
34      <li>
35        <a href="#new-jobinfo">Metode JobInfo Baru</a>
36      </li>
37
38      <li>
39        <a href="#new-jobparam">Metode JobParameter Baru</a>
40      </li>
41
42      <li>
43        <a href="#further-optimization">Mengoptimalkan Aplikasi Anda Lebih Jauh</a>
44      </li>
45    </ol>
46  </div>
47</div>
48
49<p>
50  Proses latar belakang bisa menguras memori dan baterai. Misalnya, sebuah
51  siaran implisit dapat memulai banyak proses latar belakang yang telah didaftarkan
52  untuk mendengarkannya, sekalipun proses-proses itu mungkin tidak melakukan banyak pekerjaan. Hal ini bisa
53  berdampak besar pada kinerja perangkat dan pengalaman pengguna.
54</p>
55
56<p>
57  Untuk meringankan masalah ini, Android N menerapkan pembatasan
58  berikut:
59</p>
60
61<ul>
62  <li>Aplikasi yang menargetkan Pratinjau tidak menerima siaran {@link
63  android.net.ConnectivityManager#CONNECTIVITY_ACTION} jika mereka
64  mendaftar untuk menerimanya dalam manifes mereka. Aplikasi yang berjalan tetap
65  bisa mendengarkan {@code CONNECTIVITY_CHANGE} pada thread utama mereka dengan mendaftarkan
66  {@link android.content.BroadcastReceiver} pada {@link
67  android.content.Context#registerReceiver Context.registerReceiver()}.
68  </li>
69
70  <li>Aplikasi tidak bisa mengirim atau menerima siaran {@link
71  android.hardware.Camera#ACTION_NEW_PICTURE} atau {@link
72  android.hardware.Camera#ACTION_NEW_VIDEO}. Optimalisasi ini
73  memengaruhi semua aplikasi, tidak hanya aplikasi yang menargetkan Pratinjau.
74  </li>
75</ul>
76
77<p>
78  Jika aplikasi Anda menggunakan intent ini, Anda harus membuang dependensi padanya
79  secepat mungkin agar Anda bisa menargetkan perangkat Android N dengan benar.
80  Kerangka kerja Android menyediakan beberapa solusi untuk mengurangi kebutuhan akan
81  siaran implisit ini. Misalnya, {@link android.app.job.JobScheduler}
82  dan<a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
83  {@code GcmNetworkManager}</a> menyediakan mekanisme yang tangguh untuk menjadwalkan operasi
84  jaringan bila kondisi yang ditetapkan, seperti koneksi ke jaringan
85  berbiaya tetap, terpenuhi. Anda sekarang juga bisa menggunakan {@link android.app.job.JobScheduler}
86  untuk bereaksi terhadap perubahan penyedia materi. Objek {@link android.app.job.JobInfo}
87  membungkus parameter yang digunakan {@link android.app.job.JobScheduler}
88  untuk menjadwalkan pekerjaan Anda. Bila syarat-syarat pekerjaan sudah terpenuhi, sistem
89  akan mengeksekusi pekerjaan ini pada {@link android.app.job.JobService} aplikasi Anda.
90</p>
91
92<p>
93  Dalam dokumen ini, kita akan mempelajari cara menggunakan metode alternatif, seperti
94  {@link android.app.job.JobScheduler}, untuk menyesuaikan aplikasi Anda dengan pembatasan
95  yang baru.
96</p>
97
98<h2 id="connectivity-action">
99  Pembatasan pada CONNECTIVITY_ACTION
100</h2>
101
102<p>
103  Aplikasi yang menargetkan Android N tidak menerima siaran {@link
104  android.net.ConnectivityManager#CONNECTIVITY_ACTION} jika mereka
105  mendaftar untuk menerimanya dalam manifes mereka, dan proses yang bergantung pada siaran
106  ini tidak akan dimulai. Hal ini bisa menimbulkan masalah bagi aplikasi yang ingin
107  memantau perubahan jaringan atau melakukan aktivitas jaringan dalam jumlah besar bila perangkat
108  menghubungkan ke jaringan berbiaya tetap. Beberapa solusi untuk menyiasati pembatasan
109  ini sudah ada dalam kerangka kerja Android, namun pemilihan solusi
110  yang tepat bergantung pada apa yang ingin dicapai oleh aplikasi Anda.
111</p>
112
113<p class="note">
114  <strong>Catatan:</strong> Sebuah {@link android.content.BroadcastReceiver} yang mendaftar pada
115  {@link android.content.Context#registerReceiver Context.registerReceiver()}
116  akan terus menerima siaran ini saat aplikasi berjalan.
117</p>
118
119<h3 id="sched-jobs">
120  Menjadwalkan Pekerjaan Jaringan pada Koneksi Berbiaya Tetap
121</h3>
122
123<p>
124  Saat menggunakan kelas {@link android.app.job.JobInfo.Builder JobInfo.Builder}
125  untuk membangun objek {@link android.app.job.JobInfo} Anda, terapkan metode {@link
126  android.app.job.JobInfo.Builder#setRequiredNetworkType
127  setRequiredNetworkType()} dan teruskan {@link android.app.job.JobInfo
128  JobInfo.NETWORK_TYPE_UNMETERED} sebagai parameter pekerjaan. Contoh kode berikut
129  menjadwalkan layanan yang akan dijalankan ketika perangkat terhubung ke jaringan
130  berbiaya tetap dan dikenai biaya:
131</p>
132
133<pre>
134public static final int MY_BACKGROUND_JOB = 0;
135...
136public static void scheduleJob(Context context) {
137  JobScheduler js =
138      (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
139  JobInfo job = new JobInfo.Builder(
140    MY_BACKGROUND_JOB,
141    new ComponentName(context, MyJobService.class))
142      .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
143      .setRequiresCharging(true)
144      .build();
145  js.schedule(job);
146}
147</pre>
148
149<p>
150  Bila syarat untuk pekerjaan Anda terpenuhi, aplikasi Anda akan menerima callback untuk menjalankan
151  metode {@link android.app.job.JobService#onStartJob onStartJob()} dalam
152  {@code JobService.class} yang ditetapkan. Untuk melihat contoh selengkapnya mengenai implementasi {@link
153  android.app.job.JobScheduler}, lihat <a href="{@docRoot}samples/JobScheduler/index.html">aplikasi contoh JobScheduler</a>.
154</p>
155
156<p>
157  Aplikasi yang menggunakan layanan GMSCore, dan menargetkan Android 5.0 (API level 21)
158  atau yang lebih rendah, bisa menggunakan <a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
159  {@code GcmNetworkManager}</a> dan menetapkan {@code Task.NETWORK_STATE_UNMETERED}.
160</p>
161
162<h3 id="monitor-conn">
163  Memantau Konektivitas Jaringan Saat Aplikasi Dijalankan
164</h3>
165
166<p>
167  Aplikasi yang berjalan tetap bisa memantau {@code CONNECTIVITY_CHANGE} dengan
168  {@link android.content.BroadcastReceiver} yang telah didaftarkan. Akan tetapi, {@link
169  android.net.ConnectivityManager} API menyediakan metode yang lebih tangguh untuk meminta
170  callback hanya bila persyaratan jaringan yang ditetapkan terpenuhi.
171</p>
172
173<p>
174  Objek {@link android.net.NetworkRequest} mendefinisikan parameter
175  callback jaringan dari segi {@link android.net.NetworkCapabilities}. Anda
176  membuat objek {@link android.net.NetworkRequest} dengan kelas {@link
177  android.net.NetworkRequest.Builder NetworkRequest.Builder}. {@link
178  android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest,
179  android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()}
180  kemudian meneruskan objek {@link android.net.NetworkRequest} ke sistem. Bila
181  syarat jaringan terpenuhi, aplikasi akan menerima callback untuk mengeksekusi
182  metode {@link android.net.ConnectivityManager.NetworkCallback#onAvailable
183  onAvailable()} yang didefinisikan dalam kelas {@link
184  android.net.ConnectivityManager.NetworkCallback}.
185</p>
186
187<p>
188  Aplikasi akan terus menerima callback hingga aplikasi keluar atau memanggil
189  {@link android.net.ConnectivityManager#unregisterNetworkCallback
190  unregisterNetworkCallback()}.
191</p>
192
193<h2 id="media-broadcasts">
194  Pembatasan pada NEW_PICTURE dan NEW_VIDEO
195</h2>
196
197<p>
198  Di Android N, aplikasi tidak bisa mengirim atau menerima siaran {@link
199  android.hardware.Camera#ACTION_NEW_PICTURE} atau {@link
200  android.hardware.Camera#ACTION_NEW_VIDEO}. Pembatasan ini membantu
201  meringankan dampak terhadap kinerja dan pengalaman pengguna bila beberapa aplikasi harus
202  aktif untuk memproses gambar atau video baru. Android N
203  memperluas {@link android.app.job.JobInfo} dan {@link
204  android.app.job.JobParameters} untuk menyediakan solusi alternatif.
205</p>
206
207<h3 id="new-jobinfo">
208  Metode JobInfo baru
209</h3>
210
211<p>
212  Untuk memicu pekerjaan saat perubahan URI materi, Android N memperluas
213  {@link android.app.job.JobInfo} API dengan metode berikut:
214</p>
215
216<dl>
217  <dt>
218    {@code JobInfo.TriggerContentUri()}
219  </dt>
220
221  <dd>
222    Membungkus parameter yang diperlukan untuk memicu pekerjaan saat perubahan URI materi.
223  </dd>
224
225  <dt>
226    {@code JobInfo.Builder.addTriggerContentUri()}
227  </dt>
228
229  <dd>
230    Meneruskan objek {@code TriggerContentUri} ke {@link
231    android.app.job.JobInfo}. Sebuah {@link android.database.ContentObserver}
232    akan memantau URI materi yang dibungkus. Jika terdapat beberapa objek {@code
233    TriggerContentUri} yang berhubungan dengan pekerjaan, sistem memberikan sebuah
234    callback bahkan jika itu hanya melaporkan perubahan pada salah satu URI materi.
235  </dd>
236
237  <dd>
238    Tambahkan flag {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} untuk
239    memicu pekerjaan jika ada turunan dari perubahan URI yang diberikan. Flag ini
240    berkaitan dengan parameter {@code notifyForDescendants} yang diteruskan ke {@link
241    android.content.ContentResolver#registerContentObserver
242    registerContentObserver()}.
243  </dd>
244</dl>
245
246<p class="note">
247  <strong>Catatan:</strong> {@code TriggerContentUri()} tidak bisa digunakan
248  bersama-sama dengan {@link android.app.job.JobInfo.Builder#setPeriodic
249  setPeriodic()} atau {@link android.app.job.JobInfo.Builder#setPersisted
250  setPersisted()}. Untuk terus memantau perubahan materi, jadwalkan
251  {@link android.app.job.JobInfo} baru sebelum {@link
252  android.app.job.JobService} aplikasi selesai menangani callback terbaru.
253</p>
254
255<p>
256  Kode contoh berikut menjadwalkan pekerjaan yang akan dipicu bila sistem melaporkan
257  perubahan ke URI materi, {@code MEDIA_URI}:
258</p>
259
260<pre>
261public static final int MY_BACKGROUND_JOB = 0;
262...
263public 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(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
271          JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
272  js.schedule(builder.build());
273}
274</pre>
275<p>
276  Bila sistem melaporkan perubahan dalam URI materi yang ditetapkan, aplikasi Anda
277  akan menerima callback dan objek {@link android.app.job.JobParameters}
278  akan diteruskan ke metode {@link android.app.job.JobService#onStartJob onStartJob()}
279  dalam {@code MediaContentJob.class}.
280</p>
281
282<h3 id="new-jobparam">
283  Metode JobParameter Baru
284</h3>
285
286<p>
287  Android N juga memperluas {@link android.app.job.JobParameters} untuk
288  memungkinkan aplikasi Anda menerima informasi yang berguna tentang otoritas materi
289  dan URI yang memicu pekerjaan:
290</p>
291
292<dl>
293  <dt>
294    {@code Uri[] getTriggeredContentUris()}
295  </dt>
296
297  <dd>
298    Mengembalikan larik URL yang telah memicu pekerjaan. Ini akan berupa {@code
299    null} jika tidak ada URI yang memicu pekerjaan (misalnya, pekerjaan
300    dipicu karena batas waktu atau alasan lainnya), atau jumlah
301    URI yang berubah lebih dari 50.
302  </dd>
303
304  <dt>
305    {@code String[] getTriggeredContentAuthorities()}
306  </dt>
307
308  <dd>
309    Mengembalikan larik string otoritas materi yang telah memicu pekerjaan.
310    Jika larik yang dikembalikan bukan {@code null}, gunakan {@code getTriggeredContentUris()}
311    untuk mengambil detail URI yang telah berubah.
312  </dd>
313</dl>
314
315<p>
316  Kode contoh berikut mengganti metode {@link
317  android.app.job.JobService#onStartJob JobService.onStartJob()} dan
318  mencatat otoritas materi serta URI yang telah memicu pekerjaan:
319</p>
320
321<pre>
322&#64;Override
323public 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  Mengoptimalkan Aplikasi Anda Lebih Jauh
354</h2>
355
356<p>
357  Mengoptimalkan aplikasi Anda untuk berjalan pada perangkat yang mempunyai memori rendah, atau dalam kondisi
358  memori rendah, dapat meningkatkan kinerja dan pengalaman pengguna. Membuang
359  dependensi pada layanan latar belakang dan penerima siaran
360  implisit yang terdaftar secara statis bisa membantu aplikasi Anda berjalan lebih baik pada perangkat demikian. Meskipun
361  Android N telah mengambil langkah-langkah untuk mengurangi sebagian masalah ini, Anda disarankan
362  agar mengoptimalkan aplikasi untuk berjalan tanpa menggunakan
363  proses latar belakang ini sama sekali.
364</p>
365
366<p>
367  Android N memperkenalkan beberapa tambahan perintah <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> yang
368  bisa Anda gunakan untuk menguji perilaku aplikasi dengan proses latar belakang dinonaktifkan:
369</p>
370
371<ul>
372  <li>Untuk mensimulasikan kondisi saat siaran implisit dan layanan latar belakang
373  tidak tersedia, masukkan perintah berikut:
374  </li>
375
376  <li style="list-style: none; display: inline">
377<pre class="no-pretty-print">
378{@code $ adb shell cmd appops set &lt;package&gt; RUN_IN_BACKGROUND ignore}
379</pre>
380  </li>
381
382  <li>Untuk mengaktifkan kembali siaran implisit dan layanan latar belakang, masukkan
383  perintah berikut:
384  </li>
385
386  <li style="list-style: none; display: inline">
387<pre class="no-pretty-print">
388{@code $ adb shell cmd appops set &lt;package&gt; RUN_IN_BACKGROUND allow}
389</pre>
390  </li>
391</ul>
392