Home | History | Annotate | Download | only in components
      1 page.title=Proses dan Thread
      2 page.tags=daur hidup,latar belakang
      3 
      4 @jd:body
      5 
      6 <div id="qv-wrapper">
      7 <div id="qv">
      8 
      9 <h2>Dalam dokumen ini</h2>
     10 <ol>
     11 <li><a href="#Processes">Proses</a>
     12   <ol>
     13     <li><a href="#Lifecycle">Daur hidup proses</a></li>
     14   </ol>
     15 </li>
     16 <li><a href="#Threads">Thread</a>
     17   <ol>
     18     <li><a href="#WorkerThreads">Thread pekerja</a></li>
     19     <li><a href="#ThreadSafe">Metode thread-safe</a></li>
     20   </ol>
     21 </li>
     22 <li><a href="#IPC">Komunikasi antarproses</a></li>
     23 </ol>
     24 
     25 </div>
     26 </div>
     27 
     28 <p>Bila komponen aplikasi dimulai dan tidak ada komponen aplikasi lain yang
     29 berjalan, sistem Android akan memulai proses Linux baru untuk aplikasi dengan satu thread
     30 eksekusi. Secara default, semua komponen aplikasi yang sama berjalan dalam proses dan
     31 thread yang sama (disebut thread "utama"). Jika komponen aplikasi dimulai dan sudah ada
     32 proses untuk aplikasi itu (karena komponen lain dari aplikasi itu sudah ada), maka komponen
     33 akan dimulai dalam proses itu dan menggunakan thread eksekusi yang sama. Akan tetapi, Anda bisa
     34 mengatur komponen berbeda di aplikasi agar berjalan di proses terpisah, dan Anda bisa membuat thread tambahan untuk
     35 setiap proses.</p>
     36 
     37 <p>Dokumen ini membahas cara kerja proses dan thread di aplikasi Android.</p>
     38 
     39 
     40 <h2 id="Processes">Proses</h2>
     41 
     42 <p>Secara default, semua komponen aplikasi yang sama berjalan dalam proses yang sama dan kebanyakan
     43 aplikasi tidak boleh mengubah ini. Akan tetapi, jika Anda merasa perlu mengontrol proses milik
     44 komponen tertentu, Anda dapat melakukannya dalam file manifes.</p>
     45 
     46 <p>Entri manifes untuk setiap tipe elemen komponen&mdash;<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
     47 &lt;activity&gt;}</a>, <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code
     48 &lt;service&gt;}</a>, <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
     49 &lt;receiver&gt;}</a>, dan <a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code
     50 &lt;provider&gt;}</a>&mdash;mendukung atribut {@code android:process} yang bisa menetapkan
     51 dalam proses mana komponen harus dijalankan. Anda bisa mengatur atribut ini agar setiap komponen
     52 berjalan dalam prosesnya sendiri atau agar beberapa komponen menggunakan proses yang sama sementara yang lainnya tidak.  Anda juga bisa mengatur
     53 {@code android:process} agar komponen aplikasi yang berbeda berjalan dalam proses yang sama
     54 &mdash;sepanjang aplikasi menggunakan ID Linux yang sama dan ditandatangani
     55 dengan sertifikat yang sama.</p>
     56 
     57 <p>Elemen <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
     58 &lt;application&gt;}</a> juga mendukung atribut {@code android:process}, untuk mengatur
     59 nilai default yang berlaku bagi semua komponen.</p>
     60 
     61 <p>Android bisa memutuskan untuk mematikan proses pada waktu tertentu, bila memori tinggal sedikit dan diperlukan oleh
     62 proses lain yang lebih mendesak untuk melayani pengguna. Komponen
     63 aplikasi yang berjalan dalam proses yang dimatikan maka sebagai konsekuensinya juga akan dimusnahkan.  Proses dimulai
     64 kembali untuk komponen itu bila ada lagi pekerjaan untuk mereka lakukan.</p>
     65 
     66 <p>Saat memutuskan proses yang akan dimatikan, sistem Android akan mempertimbangkan kepentingan relatifnya bagi
     67 pengguna.  Misalnya, sistem lebih mudah menghentikan proses yang menjadi host aktivitas yang tidak
     68  lagi terlihat di layar, dibandingkan dengan proses yang menjadi host aktivitas yang terlihat. Karena itu, keputusan
     69 untuk menghentikan proses bergantung pada keadaan komponen yang berjalan dalam proses tersebut. Aturan
     70 yang digunakan untuk menentukan proses yang akan dihentikan dibahas di bawah ini. </p>
     71 
     72 
     73 <h3 id="Lifecycle">Daur hidup proses</h3>
     74 
     75 <p>Sistem Android mencoba mempertahankan proses aplikasi selama mungkin, namun
     76 pada akhirnya perlu menghapus proses lama untuk mengambil kembali memori bagi proses baru atau yang lebih penting.  Untuk
     77 menentukan proses yang akan
     78 dipertahankan dan yang harus dimatikan, sistem menempatkan setiap proses ke dalam "hierarki prioritas" berdasarkan
     79 komponen yang berjalan dalam proses dan status komponen tersebut.  Proses yang memiliki
     80 prioritas terendah akan dimatikan terlebih dahulu, kemudian yang terendah berikutnya, dan seterusnya, jika perlu
     81 untuk memulihkan sumber daya sistem.</p>
     82 
     83 <p>Ada lima tingkatan dalam hierarki prioritas. Daftar berikut berisi beberapa
     84 tipe proses berdasarkan urutan prioritas (proses pertama adalah yang <em>terpenting</em> dan
     85 <em>dimatikan terakhir</em>):</p>
     86 
     87 <ol>
     88   <li><b>Proses latar depan</b>
     89     <p>Proses yang diperlukan untuk aktivitas yang sedang dilakukan pengguna.  Proses
     90 dianggap berada di latar depan jika salah satu kondisi berikut terpenuhi:</p>
     91 
     92       <ul>
     93         <li>Proses menjadi host {@link android.app.Activity} yang berinteraksi dengan pengguna dengan metode ({@link
     94 android.app.Activity}{@link android.app.Activity#onResume onResume()} telah
     95 dipanggil).</li>
     96 
     97         <li>Proses menjadi host {@link android.app.Service} yang terikat dengan aktivitas yang sedang berinteraksi dengan
     98 pengguna.</li>
     99 
    100         <li>Proses menjadi host {@link android.app.Service} yang berjalan "di latar depan"&mdash;
    101 layanan telah memanggil{@link android.app.Service#startForeground startForeground()}.
    102 
    103         <li>Proses menjadi host {@link android.app.Service} yang menjalankan salah satu callback
    104 daur hidupnya ({@link android.app.Service#onCreate onCreate()}, {@link android.app.Service#onStart
    105 onStart()}, atau {@link android.app.Service#onDestroy onDestroy()}).</li>
    106 
    107         <li>Proses menjadi host {@link android.content.BroadcastReceiver} yang menjalankan metode {@link
    108         android.content.BroadcastReceiver#onReceive onReceive()}-nya.</li>
    109     </ul>
    110 
    111     <p>Secara umum, hanya ada beberapa proses latar depan pada waktu yang diberikan.  Proses dimatikan hanya sebagai
    112 upaya terakhir&mdash; jika memori hampir habis sehingga semuanya tidak bisa terus berjalan.  Pada umumnya, pada
    113 titik itu, perangkat dalam keadaan memory paging, sehingga menghentikan beberapa proses latar depan
    114 diperlukan agar antarmuka pengguna tetap responsif.</p></li>
    115 
    116   <li><b>Proses yang terlihat</b>
    117     <p>Proses yang tidak memiliki komponen latar depan, namun masih bisa
    118 memengaruhi apa yang dilihat pengguna di layar. Proses dianggap terlihat jika salah satu kondisi
    119 berikut terpenuhi:</p>
    120 
    121       <ul>
    122         <li>Proses ini menjadi host {@link android.app.Activity} yang tidak berada di latar depan, namun masih
    123 terlihat oleh penggunanya (metode {@link android.app.Activity#onPause onPause()} telah dipanggil).
    124 Ini bisa terjadi, misalnya, jika aktivitas latar depan memulai dialog, sehingga
    125 aktivitas sebelumnya terlihat berada di belakangnya.</li>
    126 
    127         <li>Proses menjadi host {@link android.app.Service} yang terikat dengan aktivitas yang terlihat (atau latar
    128 depan)</li>
    129       </ul>
    130 
    131       <p>Proses yang terlihat dianggap sangat penting dan tidak akan dimatikan kecuali jika hal itu
    132 diperlukan agar semua proses latar depan tetap berjalan. </p>
    133     </li>
    134 
    135   <li><b>Proses layanan</b>
    136     <p>Proses yang menjalankan layanan yang telah dimulai dengan metode {@link
    137 android.content.Context#startService startService()} dan tidak termasuk dalam salah satu dari dua kategori
    138 yang lebih tinggi. Walaupun proses pelayanan tidak langsung terkait dengan semua yang dilihat oleh pengguna, proses ini
    139 umumnya melakukan hal-hal yang dipedulikan pengguna (seperti memutar musik di latar belakang
    140 atau mengunduh data di jaringan), jadi sistem membuat proses tetap berjalan kecuali memori tidak cukup untuk
    141 mempertahankannya bersama semua proses latar depan dan proses yang terlihat. </p>
    142   </li>
    143 
    144   <li><b>Proses latar belakang</b>
    145     <p>Proses yang menampung aktivitas yang saat ini tidak terlihat oleh pengguna (metode
    146 {@link android.app.Activity#onStop onStop()} aktivitas telah dipanggil). Proses ini tidak memiliki dampak
    147 langsung pada pengalaman pengguna, dan sistem bisa menghentikannya kapan saja untuk memperoleh kembali memori bagi
    148 proses latar depan, proses yang terlihat,
    149 atau proses layanan. Biasanya ada banyak proses latar belakang yang berjalan, sehingga disimpan
    150 dalam daftar LRU (least recently used atau paling sedikit digunakan) untuk memastikan bahwa proses dengan aktivitas yang paling baru
    151 terlihat oleh pengguna sebagai yang terakhir untuk dimatikan. Jika aktivitas mengimplementasikan metode
    152  daur hidupnya dengan benar, dan menyimpan statusnya saat ini, menghentikan prosesnya tidak akan memiliki efek
    153 yang terlihat pada pengalaman pengguna, karena ketika pengguna kembali ke aktivitas, aktivitas itu memulihkan
    154 semua statusnya yang terlihat. Lihat dokumen <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Aktivitas</a>
    155  untuk mendapatkan informasi tentang menyimpan dan memulihkan status.</p>
    156   </li>
    157 
    158   <li><b>Proses kosong</b>
    159     <p>Sebuah proses yang tidak berisi komponen aplikasi aktif apa pun.  Alasan satu-satunya mempertahankan proses
    160 seperti ini tetap hidup adalah untuk keperluan caching, meningkatkan waktu mulai (startup) bila
    161 nanti komponen perlu dijalankan di dalamnya.  Sistem sering menghentikan proses ini untuk menyeimbangkan sumber
    162 daya sistem secara keseluruhan antara proses cache dan cache kernel yang mendasarinya.</p>
    163   </li>
    164 </ol>
    165 
    166 
    167   <p>Android sebisa mungkin memeringkat proses setinggi
    168 mungkin, berdasarkan prioritas komponen yang sedang aktif dalam proses.  Misalnya, jika suatu proses menjadi host sebuah layanan dan
    169 aktivitas yang terlihat, proses akan diperingkat sebagai proses yang terlihat, bukan sebagai proses layanan.</p>
    170 
    171   <p>Selain itu, peringkat proses dapat meningkat karena adanya proses lain yang bergantung padanya
    172 &mdash;proses yang melayani proses lain tidak bisa diperingkat lebih rendah daripada proses yang
    173 sedang dilayaninya. Misalnya, jika penyedia konten dalam proses A melayani klien dalam proses B, atau
    174 jika layanan dalam proses A terikat dengan komponen dalam proses B, proses A selalu dipertimbangkan sebagai paling rendah
    175 prioritasnya dibandingkan dengan proses B.</p>
    176 
    177   <p>Karena proses yang menjalankan layanan diperingkat lebih tinggi daripada aktivitas latar belakang,
    178 aktivitas yang memulai operasi yang berjalan lama mungkin lebih baik memulai <a href="{@docRoot}guide/components/services.html">layanan</a> untuk operasi itu, daripada hanya
    179 membuat thread pekerja&mdash;khususnya jika operasi mungkin akan berlangsung lebih lama daripada aktivitas.
    180  Misalnya, aktivitas yang mengunggah gambar ke situs web harus memulai layanan
    181 untuk mengunggah sehingga unggahan bisa terus berjalan di latar belakang meskipun pengguna meninggalkan aktivitas tersebut.
    182 Menggunakan layanan akan memastikan operasi paling tidak memiliki prioritas "proses layanan",
    183 apa pun yang terjadi pada aktivitas. Ini menjadi alasan yang sama yang membuat penerima siaran harus
    184 menjalankan layanan daripada hanya menempatkan operasi yang menghabiskan waktu di thread.</p>
    185 
    186 
    187 
    188 
    189 <h2 id="Threads">Thread</h2>
    190 
    191 <p>Bila aplikasi diluncurkan, sistem akan membuat thread eksekusi untuk aplikasi tersebut, yang diberi nama,
    192 "main". Thread ini sangat penting karena bertugas mengirim kejadian ke widget
    193 antarmuka pengguna yang sesuai, termasuk kejadian menggambar. Ini juga merupakan thread yang
    194 membuat aplikasi berinteraksi dengan komponen dari Android UI toolkit (komponen dari paket {@link
    195 android.widget} dan {@link android.view}). Karena itu, thread 'main' juga terkadang
    196 disebut thread UI.</p>
    197 
    198 <p>Sistem ini <em>tidak</em> membuat thread terpisah untuk setiap instance komponen. Semua
    199 komponen yang berjalan di proses yang sama akan dibuat instance-nya dalam thread UI, dan sistem akan memanggil
    200 setiap komponen yang dikirim dari thread itu. Akibatnya, metode yang merespons callback sistem
    201  (seperti {@link android.view.View#onKeyDown onKeyDown()} untuk melaporkan tindakan pengguna atau metode callback daur hidup)
    202  selalu berjalan di thread UI proses.</p>
    203 
    204 <p>Misalnya saat pengguna menyentuh tombol pada layar, thread UI aplikasi akan mengirim kejadian
    205 sentuh ke widget, yang selanjutnya menetapkan status ditekan dan mengirim permintaan yang tidak divalidasi ke
    206 antrean kejadian. Thread UI akan menghapus antrean permintaan dan memberi tahu widget bahwa widget harus menggambar
    207 dirinya sendiri.</p>
    208 
    209 <p>Saat aplikasi melakukan pekerjaan intensif sebagai respons terhadap interaksi pengguna, model
    210 thread tunggal ini bisa menghasilkan kinerja yang buruk kecuali jika Anda mengimplementasikan aplikasi dengan benar. Khususnya jika
    211  semua terjadi di thread UI, melakukan operasi yang panjang seperti akses ke jaringan atau query
    212 database akan memblokir seluruh UI. Bila thread diblokir, tidak ada kejadian yang bisa dikirim,
    213 termasuk kejadian menggambar. Dari sudut pandang pengguna, aplikasi
    214 tampak mogok (hang). Lebih buruk lagi, jika thread UI diblokir selama lebih dari beberapa detik
    215 (saat ini sekitar 5 detik) pengguna akan ditampilkan dialog "<a href="http://developer.android.com/guide/practices/responsiveness.html">aplikasi tidak
    216 merespons</a>" (ANR) yang populer karena reputasi buruknya. Pengguna nanti bisa memutuskan untuk keluar dari aplikasi dan menghapus aplikasi
    217 jika mereka tidak suka.</p>
    218 
    219 <p>Selain itu, toolkit Android UI <em>bukan</em> thread-safe. Jadi, Anda tidak harus memanipulasi
    220 UI dari thread pekerja&mdash;Anda harus melakukan semua manipulasi pada antarmuka pengguna dari thread
    221 UI. Sehingga hanya ada dua aturan untuk model thread tunggal Android:</p>
    222 
    223 <ol>
    224 <li>Jangan memblokir thread UI
    225 <li>Jangan mengakses toolkit Android UI dari luar thread UI
    226 </ol>
    227 
    228 <h3 id="WorkerThreads">Thread pekerja</h3>
    229 
    230 <p>Karena model thread tunggal yang dijelaskan di atas, Anda dilarang memblokir thread
    231 UI demi daya respons UI aplikasi. Jika memiliki operasi untuk dijalankan
    232 yang tidak seketika, Anda harus memastikan untuk melakukannya di thread terpisah (thread "latar belakang" atau
    233 thread "pekerja").</p>
    234 
    235 <p>Misalnya, berikut ini beberapa kode untuk listener klik yang mengunduh gambar dari
    236 thread terpisah dan menampilkannya dalam {@link android.widget.ImageView}:</p>
    237 
    238 <pre>
    239 public void onClick(View v) {
    240     new Thread(new Runnable() {
    241         public void run() {
    242             Bitmap b = loadImageFromNetwork("http://example.com/image.png");
    243             mImageView.setImageBitmap(b);
    244         }
    245     }).start();
    246 }
    247 </pre>
    248 
    249 <p>Awalnya hal ini tampak bekerja dengan baik, karena menciptakan thread baru untuk menangani
    250 operasi jaringan. Akan tetapi, hal tersebut melanggar aturan kedua model thread tunggal: <em>jangan mengakses
    251  toolkit Android UI dari luar thread UI</em>&mdash;sampel ini memodifikasi {@link
    252 android.widget.ImageView} dari thread pekerja sebagai ganti thread UI. Ini bisa
    253 mengakibatkan perilaku yang tidak terdefinisi dan tidak diharapkan, yang bisa menyulitkan dan menghabiskan waktu untuk melacaknya.</p>
    254 
    255 <p>Untuk memperbaiki masalah ini, Android menawarkan beberapa cara untuk mengakses thread UI dari
    256 thread lainnya. Berikut ini daftar metode yang bisa membantu:</p>
    257 
    258 <ul>
    259 <li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable)
    260 Activity.runOnUiThread(Runnable)}</li>
    261 <li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li>
    262 <li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable,
    263 long)}</li>
    264 </ul>
    265 
    266 <p>Misalnya, Anda bisa memperbaiki kode di atas dengan menggunakan metode {@link
    267 android.view.View#post(java.lang.Runnable) View.post(Runnable)}:</p>
    268 
    269 <pre>
    270 public void onClick(View v) {
    271     new Thread(new Runnable() {
    272         public void run() {
    273             final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
    274             mImageView.post(new Runnable() {
    275                 public void run() {
    276                     mImageView.setImageBitmap(bitmap);
    277                 }
    278             });
    279         }
    280     }).start();
    281 }
    282 </pre>
    283 
    284 <p>Kini implementasi ini thread-safe: operasi jaringan dilakukan terpisah dari thread
    285  sementara {@link android.widget.ImageView} dimanipulasi dari thread UI.</p>
    286 
    287 <p>Akan tetapi, karena operasi semakin kompleks, jenis kode seperti ini bisa semakin rumit
    288 dan sulit dipertahankan. Untuk menangani interaksi yang lebih kompleks dengan thread pekerja, Anda bisa mempertimbangkan
    289  penggunaan {@link android.os.Handler}di thread pekerja, untuk memproses pesan yang dikirim dari
    290  thread UI. Mungkin solusi terbaiknya adalah memperpanjang kelas {@link android.os.AsyncTask},
    291 yang akan menyederhanakan eksekusi tugas-tugas thread pekerja yang perlu berinteraksi dengan UI.</p>
    292 
    293 
    294 <h4 id="AsyncTask">Menggunakan AsyncTask</h4>
    295 
    296 <p>Dengan {@link android.os.AsyncTask}, Anda bisa melakukan pekerjaan asinkron pada antarmuka
    297 pengguna. AsyncTask memblokir operasi di thread pekerja kemudian mempublikasikan hasilnya
    298 di thread UI, tanpa mengharuskan Anda untuk menangani sendiri thread dan/atau handler sendiri.</p>
    299 
    300 <p>Untuk menggunakannya, Anda harus menempatkan {@link android.os.AsyncTask} sebagai subkelas dan mengimplementasikan metode callback {@link
    301 android.os.AsyncTask#doInBackground doInBackground()} yang berjalan di kumpulan
    302 thread latar belakang. Untuk memperbarui UI, Anda harus mengimplementasikan {@link
    303 android.os.AsyncTask#onPostExecute onPostExecute()}, yang memberikan hasil dari {@link
    304 android.os.AsyncTask#doInBackground doInBackground()} dan berjalan di thread UI, jadi Anda bisa
    305 memperbarui UI dengan aman. Selanjutnya Anda bisa menjalankan tugas dengan memanggil {@link android.os.AsyncTask#execute execute()}
    306 dari thread UI.</p>
    307 
    308 <p>Misalnya, Anda bisa mengimplementasikan contoh sebelumnya menggunakan {@link android.os.AsyncTask} dengan cara
    309 ini:</p>
    310 
    311 <pre>
    312 public void onClick(View v) {
    313     new DownloadImageTask().execute("http://example.com/image.png");
    314 }
    315 
    316 private class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
    317     /** The system calls this to perform work in a worker thread and
    318       * delivers it the parameters given to AsyncTask.execute() */
    319     protected Bitmap doInBackground(String... urls) {
    320         return loadImageFromNetwork(urls[0]);
    321     }
    322 
    323     /** The system calls this to perform work in the UI thread and delivers
    324       * the result from doInBackground() */
    325     protected void onPostExecute(Bitmap result) {
    326         mImageView.setImageBitmap(result);
    327     }
    328 }
    329 </pre>
    330 
    331 <p>Kini UI aman dan kode jadi lebih sederhana, karena memisahkan pekerjaan ke
    332 dalam bagian-bagian yang harus dilakukan pada thread pekerja dan thread UI.</p>
    333 
    334 <p>Anda harus membaca acuan {@link android.os.AsyncTask} untuk memahami sepenuhnya
    335 cara menggunakan kelas ini, namun berikut ini ikhtisar singkat cara kerjanya:</p>
    336 
    337 <ul>
    338 <li>Anda bisa menetapkan tipe parameter, nilai kemajuan, dan nilai
    339  akhir tugas, dengan menggunakan generik</li>
    340 <li>Metode {@link android.os.AsyncTask#doInBackground doInBackground()} berjalan secara otomatis pada
    341 thread pekerja</li>
    342 <li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}, {@link
    343 android.os.AsyncTask#onPostExecute onPostExecute()}, dan {@link
    344 android.os.AsyncTask#onProgressUpdate onProgressUpdate()} semuanya dipanggil pada thread UI</li>
    345 <li>Nilai yang dikembalikan oleh {@link android.os.AsyncTask#doInBackground doInBackground()} akan dikirim ke
    346 {@link android.os.AsyncTask#onPostExecute onPostExecute()}</li>
    347 <li>Anda bisa memangil {@link android.os.AsyncTask#publishProgress publishProgress()} setiap saat di {@link
    348 android.os.AsyncTask#doInBackground doInBackground()} untuk mengeksekusi {@link
    349 android.os.AsyncTask#onProgressUpdate onProgressUpdate()} pada thread UI</li>
    350 <li>Anda bisa membatalkan tugas ini kapan saja, dari thread mana saja</li>
    351 </ul>
    352 
    353 <p class="caution"><strong>Perhatian:</strong> Masalah lain yang mungkin Anda temui saat menggunakan
    354 thread pekerja adalah restart tak terduga dalam aktivitas karena <a href="{@docRoot}guide/topics/resources/runtime-changes.html">perubahan konfigurasi runtime</a>
    355  (seperti saat pengguna mengubah orientasi layar), yang bisa memusnahkan thread pekerja. Untuk
    356 melihat cara mempertahankan tugas selama restart ini dan cara membatalkan
    357 tugas dengan benar saat aktivitas dimusnahkan, lihat kode sumber untuk aplikasi sampel <a href="http://code.google.com/p/shelves/">Shelves</a>.</p>
    358 
    359 
    360 <h3 id="ThreadSafe">Metode thread-safe</h3>
    361 
    362 <p> Dalam beberapa situasi, metode yang Anda implementasikan bisa dipanggil dari lebih dari satu thread,
    363 dan karena itu harus ditulis agar menjadi thread-safe. </p>
    364 
    365 <p>Ini terutama terjadi untuk metode yang bisa dipanggil dari jauh &mdash;seperti metode dalam <a href="{@docRoot}guide/components/bound-services.html">layanan terikat</a>. Bila sebuah panggilan pada
    366 metode yang dijalankan dalam {@link android.os.IBinder} berasal dari proses yang sama di mana
    367 {@link android.os.IBinder IBinder} berjalan, metode ini akan dieksekusi di thread pemanggil.
    368 Akan tetapi, bila panggilan berasal proses lain, metode akan dieksekusi dalam thread yang dipilih dari
    369  kumpulan (pool) thread yang dipertahankan sistem dalam proses yang sama seperti{@link android.os.IBinder
    370 IBinder} (tidak dieksekusi dalam thread UI proses).  Misalnya, karena metode
    371 {@link android.app.Service#onBind onBind()} layanan akan dipanggil dari thread UI
    372 proses layanan, metode yang diimplementasikan dalam objek yang dikembalikan {@link android.app.Service#onBind
    373 onBind()} (misalnya, subkelas yang mengimplementasikan metode RPC) akan dipanggil dari thread
    374 di pool. Karena layanan bisa memiliki lebih dari satu klien, maka lebih dari satu pool thread bisa melibatkan
    375  metode {@link android.os.IBinder IBinder} yang sama sekaligus. Metode {@link android.os.IBinder
    376 IBinder} karenanya harus diimplementasikan sebagai thread-safe.</p>
    377 
    378 <p> Penyedia konten juga bisa menerima permintaan data yang berasal dalam proses lain.
    379 Meskipun kelas {@link android.content.ContentResolver} dan {@link android.content.ContentProvider}
    380  menyembunyikan detail cara komunikasi antarproses dikelola, metode {@link
    381 android.content.ContentProvider} yang merespons permintaan itu&mdash;metode {@link
    382 android.content.ContentProvider#query query()}, {@link android.content.ContentProvider#insert
    383 insert()}, {@link android.content.ContentProvider#delete delete()}, {@link
    384 android.content.ContentProvider#update update()}, dan {@link android.content.ContentProvider#getType
    385 getType()}&mdash; dipanggil dari pool thread pada proses penyedia konten, bukan thread UI
    386 untuk proses tersebut.  Mengingat metode ini bisa dipanggil dari thread mana pun
    387 sekaligus, metode-metode ini juga harus diimplementasikan sebagai thread-safe. </p>
    388 
    389 
    390 <h2 id="IPC">Komunikasi Antarproses</h2>
    391 
    392 <p>Android menawarkan mekanisme komunikasi antarproses (IPC) menggunakan panggilan prosedur jauh
    393  (RPC), yang mana metode ini dipanggil oleh aktivitas atau komponen aplikasi lain, namun dieksekusi dari
    394 jauh (di proses lain), bersama hasil yang dikembalikan ke
    395 pemanggil. Ini mengharuskan penguraian panggilan metode dan datanya ke tingkat yang bisa
    396 dipahami sistem operasi, mentransmisikannya dari proses lokal dan ruang alamat untuk proses jauh
    397 dan ruang proses, kemudian merakit kembali dan menetapkannya kembali di sana.  Nilai-nilai yang dikembalikan
    398 akan ditransmisikan dalam arah berlawanan.  Android menyediakan semua kode untuk melakukan transaksi IPC
    399  ini, sehingga Anda bisa fokus pada pendefinisian dan implementasi antarmuka pemrograman RPC. </p>
    400 
    401 <p>Untuk melakukan IPC, aplikasi Anda harus diikat ke layanan, dengan menggunakan {@link
    402 android.content.Context#bindService bindService()}. Untuk informasi selengkapnya, lihat panduan pengembang <a href="{@docRoot}guide/components/services.html">Layanan</a>.</p>
    403 
    404 
    405 <!--
    406 <h2>Beginner's Path</h2>
    407 
    408 <p>For information about how to perform work in the background for an indefinite period of time
    409 (without a user interface), continue with the <b><a
    410 href="{@docRoot}guide/components/services.html">Services</a></b> document.</p>
    411 -->
    412