Home | History | Annotate | Download | only in features
      1 page.title=Optimalisasi Latar Belakang
      2 page.metaDescription=Pembatasan baru pada siaran implisit.
      3 page.keywords="android N", "implicit broadcasts", "job scheduler"
      4 page.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>
    134 public static final int MY_BACKGROUND_JOB = 0;
    135 ...
    136 public 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>
    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(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
    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   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