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@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 <package> 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 <package> RUN_IN_BACKGROUND allow} 389</pre> 390 </li> 391</ul> 392