Home | History | Annotate | Download | only in components
      1 page.title=Layanan Terikat
      2 parent.title=Layanan
      3 parent.link=services.html
      4 @jd:body
      5 
      6 
      7 <div id="qv-wrapper">
      8 <ol id="qv">
      9 <h2>Dalam dokumen ini</h2>
     10 <ol>
     11   <li><a href="#Basics">Dasar-Dasar</a></li>
     12   <li><a href="#Creating">Membuat Layanan Terikat</a>
     13     <ol>
     14       <li><a href="#Binder">Memperluas kelas Binder</a></li>
     15       <li><a href="#Messenger">Menggunakan Messenger</a></li>
     16     </ol>
     17   </li>
     18   <li><a href="#Binding">Mengikat ke Layanan</a></li>
     19   <li><a href="#Lifecycle">Mengelola Daur Hidup Layanan Terikat</a></li>
     20 </ol>
     21 
     22 <h2>Kelas-kelas utama</h2>
     23 <ol>
     24   <li>{@link android.app.Service}</li>
     25   <li>{@link android.content.ServiceConnection}</li>
     26   <li>{@link android.os.IBinder}</li>
     27 </ol>
     28 
     29 <h2>Contoh</h2>
     30 <ol>
     31   <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
     32       RemoteService}</a></li>
     33   <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
     34       LocalService}</a></li>
     35 </ol>
     36 
     37 <h2>Lihat juga</h2>
     38 <ol>
     39   <li><a href="{@docRoot}guide/components/services.html">Layanan</a></li>
     40 </ol>
     41 </div>
     42 
     43 
     44 <p>Layanan terikat adalah server di antarmuka klien-server. Layanan terikat memungkinkan komponen-komponen
     45 (seperti aktivitas) untuk diikat ke layanan, mengirim permintaan, menerima respons, dan bahkan melakukan
     46 komunikasi antarproses (IPC). Layanan terikat biasanya hidup hanya saat melayani
     47 komponen aplikasi lain dan tidak berjalan di latar belakang terus-menerus.</p>
     48 
     49 <p>Dokumen ini menampilkan cara membuat layanan terikat, termasuk cara mengikat
     50 ke layanan dari komponen aplikasi lain. Akan tetapi, Anda juga harus mengacu dokumen <a href="{@docRoot}guide/components/services.html">Layanan</a> untuk
     51 informasi tambahan tentang layanan secara umum, seperti cara menyampaikan pemberitahuan dari layanan, mengatur
     52 layanan agar berjalan di latar depan, dan lain-lain.</p>
     53 
     54 
     55 <h2 id="Basics">Dasar-Dasar</h2>
     56 
     57 <p>Layanan terikat adalah implementasi kelas {@link android.app.Service} yang memungkinkan
     58 aplikasi lain diikat padanya dan berinteraksi dengannya. Untuk menyediakan pengikatan bagi sebuah
     59 layanan, Anda harus mengimplementasikan metode callback {@link android.app.Service#onBind onBind()}. Metode ini
     60 menghasilkan objek {@link android.os.IBinder} yang mendefinisikan antarmuka pemprograman yang
     61 bisa digunakan klien untuk berinteraksi dengan layanan.</p>
     62 
     63 <div class="sidebox-wrapper">
     64 <div class="sidebox">
     65   <h3>Mengikat ke Layanan yang Sudah Dimulai</h3>
     66 
     67 <p>Seperti dibahas dalam dokumen <a href="{@docRoot}guide/components/services.html">Layanan</a>
     68 , Anda bisa membuat layanan yang dimulai sekaligus diikat. Yakni, layanan bisa
     69 dimulai dengan memanggil {@link android.content.Context#startService startService()}, yang memungkinkan
     70 layanan berjalan terus-menerus, dan juga membolehkan klien untuk mengikat ke layanan dengan memanggil {@link
     71 android.content.Context#bindService bindService()}.
     72   <p>Jika Anda mengizinkan layanan dimulai dan diikat, lalu ketika layanan telah
     73 dimulai, sistem <em>tidak</em> menghapus layanan ketika semua klien melepas ikatan. Sebagai gantinya, Anda harus
     74 menghentikan layanan secara eksplisit, dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau {@link
     75 android.content.Context#stopService stopService()}.</p>
     76 
     77 <p>Walaupun Anda biasanya harus mengimplementasikan {@link android.app.Service#onBind onBind()}
     78 <em>atau</em> {@link android.app.Service#onStartCommand onStartCommand()}, kadang-kadang perlu
     79 mengimplementasikan keduanya. Misalnya, sebuah pemutar musik bisa merasakan manfaatnya karena layanannya boleh berjalan
     80 terus-menerus dan juga menyediakan pengikatan. Dengan cara ini, sebuah aktivitas bisa memulai layanan untuk memutar beberapa
     81 lagu dan musik terus dimainkan sekalipun pengguna meninggalkan aplikasi. Lalu, bila pengguna
     82 kembali ke aplikasi, aktivitas bisa mengikat ke layanan untuk mendapatkan kembali kontrol atas pemutaran.</p>
     83 
     84 <p>Pastikan membaca bagian tentang <a href="#Lifecycle">Mengelola Daur Hidup Layanan
     85 Terikat</a>, untuk informasi selengkapnya tentang daur hidup layanan saat menambahkan pengikatan ke
     86 layanan yang sudah dimulai.</p>
     87 </div>
     88 </div>
     89 
     90 <p>Klien bisa mengikat ke layanan dengan memanggil {@link android.content.Context#bindService
     91 bindService()}. Bila itu dilakukan, klien harus menyediakan implementasi {@link
     92 android.content.ServiceConnection}, yang memantau koneksi dengan layanan. Metode {@link
     93 android.content.Context#bindService bindService()} kembali dengan serta-merta tanpa sebuah nilai, namun
     94 bila sistem Android membuat koneksi antara klien
     95 dan layanan, sistem akan memanggil {@link
     96 android.content.ServiceConnection#onServiceConnected onServiceConnected()} pada {@link
     97 android.content.ServiceConnection} untuk mengirim {@link android.os.IBinder} yang
     98 bisa digunakan klien untuk berkomunikasi dengan layanan.</p>
     99 
    100 <p>Beberapa klien bisa terhubung ke layanan dengan serentak. Akan tetapi, sistem akan memanggil metode
    101 {@link android.app.Service#onBind onBind()} layanan Anda untuk mengambil {@link android.os.IBinder} hanya
    102 bila klien pertama mengikat. Sistem lalu memberikan {@link android.os.IBinder} yang sama ke setiap
    103 klien tambahan yang mengikat, tanpa memanggil {@link android.app.Service#onBind onBind()} lagi.</p>
    104 
    105 <p>Bila klien terakhir melepas ikatan dari layanan, sistem akan menghapus layanan (kecuali jika
    106 layanan juga dimulai oleh {@link android.content.Context#startService startService()}).</p>
    107 
    108 <p>Bila Anda mengimplementasikan layanan terikat, yang terpenting adalah mendefinisikan antarmuka
    109 yang dihasilkan metode callback {@link android.app.Service#onBind onBind()} Anda. Ada sedikit
    110 cara mendefinisikan antarmuka {@link android.os.IBinder} layanan Anda dan bagian berikut
    111 akan membahas masing-masing teknik.</p>
    112 
    113 
    114 
    115 <h2 id="Creating">Membuat Layanan Terikat</h2>
    116 
    117 <p>Saat membuat layanan yang menyediakan pengikatan, Anda harus menyediakan {@link android.os.IBinder}
    118 yang menyediakan antarmuka pemrograman yang bisa digunakan klien untuk berinteraksi dengan layanan. Ada
    119 tiga cara untuk mendefinisikan antarmuka:</p>
    120 
    121 <dl>
    122   <dt><a href="#Binder">Memperluas kelas Binder</a></dt>
    123   <dd>Jika layanan Anda bersifat privat untuk aplikasi Anda sendiri dan berjalan dalam proses yang sama dengan klien
    124 (biasanya), Anda harus membuat antarmuka dengan memperluas kelas {@link android.os.Binder}
    125 dan menghasilkan instance dari
    126 {@link android.app.Service#onBind onBind()}. Klien akan menerima {@link android.os.Binder} dan
    127 bisa menggunakannya untuk mengakses langsung metode publik yang tersedia dalam implementasi {@link android.os.Binder}
    128 atau bahkan {@link android.app.Service}.
    129   <p>Inilah teknik yang lebih disukai bila layanan Anda sekadar pekerja latar belakang untuk aplikasi Anda
    130 sendiri. Satu-satunya alasan tidak membuat antarmuka dengan cara ini adalah karena
    131 layanan Anda akan digunakan oleh aplikasi lain atau pada proses-proses terpisah.</dd>
    132 
    133   <dt><a href="#Messenger">Menggunakan Messenger</a></dt>
    134   <dd>Jika antarmuka Anda perlu bekerja lintas proses, Anda bisa membuat
    135 antarmuka untuk layanan dengan {@link android.os.Messenger}. Dengan cara ini, layanan
    136 mendefinisikan {@link android.os.Handler} yang akan merespons aneka tipe objek {@link
    137 android.os.Message}. {@link android.os.Handler}
    138 ini adalah dasar bagi {@link android.os.Messenger} yang nanti bisa berbagi {@link android.os.IBinder}
    139 dengan klien, sehingga memungkinkan klien mengirim perintah ke layanan dengan menggunakan objek {@link
    140 android.os.Message}. Selain itu, klien bisa mendefinisikan sendiri {@link android.os.Messenger} 
    141 sehingga layanan bisa mengirim balik pesan.
    142   <p>Inilah cara termudah melakukan komunikasi antarproses (IPC), karena {@link
    143 android.os.Messenger} akan mengantre semua permintaan ke dalam satu thread sehingga Anda tidak perlu mendesain
    144 layanan agar thread-safe.</p>
    145   </dd>
    146 
    147   <dt>Menggunakan AIDL</dt>
    148   <dd>AIDL (Android Interface Definition Language) melakukan semua pekerjaan untuk mengurai objek menjadi
    149 primitif yang bisa dipahami dan diarahkan oleh sistem operasi ke berbagai proses untuk melakukan
    150 IPC. Teknik sebelumnya, dengan menggunakan {@link android.os.Messenger}, sebenarnya berdasarkan AIDL sebagai
    151 struktur yang mendasarinya. Seperti disebutkan di atas, {@link android.os.Messenger} membuat antrean
    152 semua permintaan klien dalam satu thread, sehingga layanan akan menerima permintaan satu per satu. Akan tetapi,
    153 jika ingin layanan Anda menangani beberapa permintaan sekaligus, Anda bisa menggunakan AIDL
    154 secara langsung. Dalam hal ini, layanan Anda harus mampu multi-thread dan dibuat thread-safe.
    155   <p>Untuk menggunakan AIDL secara langsung, Anda harus
    156 membuat file {@code .aidl} yang mendefinisikan antarmuka pemrograman. Alat Android SDK menggunakan
    157 file ini untuk menghasilkan kelas abstrak yang mengimplementasikan antarmuka dan menangani IPC, yang nanti
    158 bisa Anda perluas dalam layanan.</p>
    159   </dd>
    160 </dl>
    161 
    162   <p class="note"><strong>Catatan:</strong> Umumnya aplikasi <strong>tidak boleh</strong> menggunakan AIDL untuk
    163 membuat layanan terikat, karena hal itu mungkin memerlukan kemampuan multi-thread dan
    164 bisa mengakibatkan implementasi yang lebih rumit. Dengan demikian, AIDL tidak cocok untuk sebagian besar aplikasi
    165 dan dokumen ini tidak membahas cara menggunakannya untuk layanan Anda. Jika Anda yakin perlu
    166 menggunakan AIDL secara langsung, lihat dokumen <a href="{@docRoot}guide/components/aidl.html">AIDL</a>
    167 .</p>
    168 
    169 
    170 
    171 
    172 <h3 id="Binder">Memperluas kelas Binder</h3>
    173 
    174 <p>Jika layanan Anda hanya digunakan oleh aplikasi lokal dan tidak perlu bekerja lintas proses,
    175 maka Anda bisa mengimplementasikan kelas {@link android.os.Binder} Anda sendiri yang memberi klien Anda
    176 akses langsung ke metode publik dalam layanan.</p>
    177 
    178 <p class="note"><strong>Catatan:</strong> Hal ini hanya berhasil jika klien dan layanan berada dalam
    179 aplikasi dan proses yang sama, suatu kondisi yang paling umum. Misalnya, cara ini sangat cocok untuk sebuah aplikasi musik
    180 yang perlu mengikat aktivitas ke layanannya sendiri, yakni memutar musik di
    181 latar belakang.</p>
    182 
    183 <p>Berikut cara menyiapkannya:</p>
    184 <ol>
    185   <li>Dalam layanan Anda, buat sebuah instance {@link android.os.Binder} yang:
    186     <ul>
    187       <li>berisi metode publik yang bisa dipanggil klien</li>
    188       <li>menghasilkan instance {@link android.app.Service} saat ini, yang memiliki metode publik yang
    189 bisa dipanggil klien</li>
    190       <li>atau, menghasilkan instance kelas lain yang host-nya di layanan dengan metode publik yang
    191 bisa dipanggil klien</li>
    192     </ul>
    193   <li>Hasilkan instance {@link android.os.Binder} ini dari metode callback {@link
    194 android.app.Service#onBind onBind()}.</li>
    195   <li>Di klien, terima {@link android.os.Binder} dari metode callback {@link
    196 android.content.ServiceConnection#onServiceConnected onServiceConnected()} dan
    197 buat panggilan ke layanan terikat dengan menggunakan metode yang disediakan.</li>
    198 </ol>
    199 
    200 <p class="note"><strong>Catatan:</strong> Alasan layanan dan klien harus berada dalam aplikasi yang sama
    201 adalah agar klien bisa mengkonversi objek yang dihasilkan dan memanggil API-nya dengan benar. Layanan
    202 dan klien juga harus berada dalam proses yang sama, karena teknik ini tidak melakukan
    203 pengarahan (marshalling) apa pun untuk lintas proses.</p>
    204 
    205 <p>Misalnya, berikut ini adalah layanan yang memberi klien akses ke metode-metode dalam layanan melalui
    206 implementasi {@link android.os.Binder}:</p>
    207 
    208 <pre>
    209 public class LocalService extends Service {
    210     // Binder given to clients
    211     private final IBinder mBinder = new LocalBinder();
    212     // Random number generator
    213     private final Random mGenerator = new Random();
    214 
    215     /**
    216      * Class used for the client Binder.  Because we know this service always
    217      * runs in the same process as its clients, we don't need to deal with IPC.
    218      */
    219     public class LocalBinder extends Binder {
    220         LocalService getService() {
    221             // Return this instance of LocalService so clients can call public methods
    222             return LocalService.this;
    223         }
    224     }
    225 
    226     &#64;Override
    227     public IBinder onBind(Intent intent) {
    228         return mBinder;
    229     }
    230 
    231     /** method for clients */
    232     public int getRandomNumber() {
    233       return mGenerator.nextInt(100);
    234     }
    235 }
    236 </pre>
    237 
    238 <p>{@code LocalBinder} menyediakan {@code getService()} metode bagi klien untuk mengambil
    239 instance {@code LocalService} saat ini. Cara ini memungkinkan klien memanggil metode publik dalam
    240 layanan. Misalnya, klien bisa memanggil {@code getRandomNumber()} dari layanan.</p>
    241 
    242 <p>Berikut ini adalah aktivitas yang mengikat ke {@code LocalService} dan memanggil {@code getRandomNumber()}
    243 bila tombol diklik:</p>
    244 
    245 <pre>
    246 public class BindingActivity extends Activity {
    247     LocalService mService;
    248     boolean mBound = false;
    249 
    250     &#64;Override
    251     protected void onCreate(Bundle savedInstanceState) {
    252         super.onCreate(savedInstanceState);
    253         setContentView(R.layout.main);
    254     }
    255 
    256     &#64;Override
    257     protected void onStart() {
    258         super.onStart();
    259         // Bind to LocalService
    260         Intent intent = new Intent(this, LocalService.class);
    261         bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    262     }
    263 
    264     &#64;Override
    265     protected void onStop() {
    266         super.onStop();
    267         // Unbind from the service
    268         if (mBound) {
    269             unbindService(mConnection);
    270             mBound = false;
    271         }
    272     }
    273 
    274     /** Called when a button is clicked (the button in the layout file attaches to
    275       * this method with the android:onClick attribute) */
    276     public void onButtonClick(View v) {
    277         if (mBound) {
    278             // Call a method from the LocalService.
    279             // However, if this call were something that might hang, then this request should
    280             // occur in a separate thread to avoid slowing down the activity performance.
    281             int num = mService.getRandomNumber();
    282             Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
    283         }
    284     }
    285 
    286     /** Defines callbacks for service binding, passed to bindService() */
    287     private ServiceConnection mConnection = new ServiceConnection() {
    288 
    289         &#64;Override
    290         public void onServiceConnected(ComponentName className,
    291                 IBinder service) {
    292             // We've bound to LocalService, cast the IBinder and get LocalService instance
    293             LocalBinder binder = (LocalBinder) service;
    294             mService = binder.getService();
    295             mBound = true;
    296         }
    297 
    298         &#64;Override
    299         public void onServiceDisconnected(ComponentName arg0) {
    300             mBound = false;
    301         }
    302     };
    303 }
    304 </pre>
    305 
    306 <p>Contoh di atas menampilkan cara klien mengikat ke layanan dengan menggunakan implementasi
    307 {@link android.content.ServiceConnection} dan callback {@link
    308 android.content.ServiceConnection#onServiceConnected onServiceConnected()}. Bagian
    309 berikut menyediakan informasi selengkapnya tentang proses pengikatan ke layanan.</p>
    310 
    311 <p class="note"><strong>Catatan:</strong> Contoh di atas tidak secara eksplisit melepas ikatan dari layanan,
    312 namun semua klien harus melepas ikatan pada waktu yang tepat (seperti saat aktivitas sedang jeda).</p>
    313 
    314 <p>Untuk contoh kode selengkapnya, lihat kelas <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
    315 LocalService.java}</a> dan kelas <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code
    316 LocalServiceActivities.java}</a> dalam <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
    317 
    318 
    319 
    320 
    321 
    322 <h3 id="Messenger">Menggunakan Messenger</h3>
    323 
    324 <div class="sidebox-wrapper">
    325 <div class="sidebox">
    326   <h4>Dibandingkan dengan AIDL</h4>
    327   <p>Bila Anda perlu melakukan IPC, menggunakan {@link android.os.Messenger} untuk antarmuka
    328 lebih sederhana daripada mengimplementasikannya dengan AIDL, karena {@link android.os.Messenger} mengantre
    329 semua panggilan ke layanan, sementara antarmuka AIDL murni mengirim permintaan serentak ke
    330 layanan, yang nanti harus menangani multi-threading.</p>
    331   <p>Untuk sebagian besar aplikasi, layanan tidak perlu melakukan multi-threading, jadi dengan menggunakan {@link
    332 android.os.Messenger} memungkinkan layanan menangani panggilan satu per satu. Jika
    333 layanan harus multi-thread, Anda harus menggunakan <a href="{@docRoot}guide/components/aidl.html">AIDL</a> untuk mendefinisikan antarmuka.</p>
    334 </div>
    335 </div>
    336 
    337 <p>Jika layanan perlu berkomunikasi dengan proses jauh, Anda bisa menggunakan
    338 {@link android.os.Messenger} untuk menyediakan antarmuka bagi layanan Anda. Teknik ini memungkinkan
    339 Anda melakukan komunikasi antarproses (IPC) tanpa harus menggunakan AIDL.</p>
    340 
    341 <p>Berikut ini rangkuman cara menggunakan {@link android.os.Messenger}:</p>
    342 
    343 <ul>
    344   <li>Layanan mengimplementasikan {@link android.os.Handler} yang menerima callback untuk tiap
    345 panggilan dari klien.</li>
    346   <li>{@link android.os.Handler} digunakan untuk membuat objek {@link android.os.Messenger}
    347 (yang merupakan acuan ke {@link android.os.Handler}).</li>
    348   <li>{@link android.os.Messenger} membuat {@link android.os.IBinder} yang
    349 dikembalikan layanan ke klien dari {@link android.app.Service#onBind onBind()}.</li>
    350   <li>Klien menggunakan {@link android.os.IBinder} untuk membuat instance {@link android.os.Messenger}
    351 (yang mengacu {@link android.os.Handler} layanan), yang digunakan klien untuk mengirim
    352 objek {@link android.os.Message} ke layanan.</li>
    353   <li>Layanan menerima setiap {@link android.os.Message} dalam {@link
    354 android.os.Handler}&mdash;secara spesifik, dalam metode {@link android.os.Handler#handleMessage
    355 handleMessage()}.</li>
    356 </ul>
    357 
    358 
    359 <p>Dengan cara ini, tidak ada "metode" untuk dipanggil klien pada layanan. Sebagai gantinya,
    360 klien mengirim "pesan" (objek-objek {@link android.os.Message}) yang diterima layanan dalam
    361 {@link android.os.Handler}-nya.</p>
    362 
    363 <p>Berikut ini contoh layanan sederhana yang menggunakan antarmuka {@link android.os.Messenger}:</p>
    364 
    365 <pre>
    366 public class MessengerService extends Service {
    367     /** Command to the service to display a message */
    368     static final int MSG_SAY_HELLO = 1;
    369 
    370     /**
    371      * Handler of incoming messages from clients.
    372      */
    373     class IncomingHandler extends Handler {
    374         &#64;Override
    375         public void handleMessage(Message msg) {
    376             switch (msg.what) {
    377                 case MSG_SAY_HELLO:
    378                     Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
    379                     break;
    380                 default:
    381                     super.handleMessage(msg);
    382             }
    383         }
    384     }
    385 
    386     /**
    387      * Target we publish for clients to send messages to IncomingHandler.
    388      */
    389     final Messenger mMessenger = new Messenger(new IncomingHandler());
    390 
    391     /**
    392      * When binding to the service, we return an interface to our messenger
    393      * for sending messages to the service.
    394      */
    395     &#64;Override
    396     public IBinder onBind(Intent intent) {
    397         Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
    398         return mMessenger.getBinder();
    399     }
    400 }
    401 </pre>
    402 
    403 <p>Perhatikan bahwa metode {@link android.os.Handler#handleMessage handleMessage()} dalam
    404 {@link android.os.Handler} adalah tempat layanan menerima {@link android.os.Message}
    405 yang masuk dan memutuskan aksi yang harus dilakukan, berdasarkan anggota {@link android.os.Message#what}.</p>
    406 
    407 <p>Klien tinggal membuat {@link android.os.Messenger} berdasarkan {@link
    408 android.os.IBinder} yang dihasilkan layanan dan mengirim pesan menggunakan {@link
    409 android.os.Messenger#send send()}. Misalnya, berikut ini adalah aktivitas sederhana yang mengikat ke
    410 layanan dan mengirim pesan {@code MSG_SAY_HELLO} ke layanan:</p>
    411 
    412 <pre>
    413 public class ActivityMessenger extends Activity {
    414     /** Messenger for communicating with the service. */
    415     Messenger mService = null;
    416 
    417     /** Flag indicating whether we have called bind on the service. */
    418     boolean mBound;
    419 
    420     /**
    421      * Class for interacting with the main interface of the service.
    422      */
    423     private ServiceConnection mConnection = new ServiceConnection() {
    424         public void onServiceConnected(ComponentName className, IBinder service) {
    425             // This is called when the connection with the service has been
    426             // established, giving us the object we can use to
    427             // interact with the service.  We are communicating with the
    428             // service using a Messenger, so here we get a client-side
    429             // representation of that from the raw IBinder object.
    430             mService = new Messenger(service);
    431             mBound = true;
    432         }
    433 
    434         public void onServiceDisconnected(ComponentName className) {
    435             // This is called when the connection with the service has been
    436             // unexpectedly disconnected -- that is, its process crashed.
    437             mService = null;
    438             mBound = false;
    439         }
    440     };
    441 
    442     public void sayHello(View v) {
    443         if (!mBound) return;
    444         // Create and send a message to the service, using a supported 'what' value
    445         Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
    446         try {
    447             mService.send(msg);
    448         } catch (RemoteException e) {
    449             e.printStackTrace();
    450         }
    451     }
    452 
    453     &#64;Override
    454     protected void onCreate(Bundle savedInstanceState) {
    455         super.onCreate(savedInstanceState);
    456         setContentView(R.layout.main);
    457     }
    458 
    459     &#64;Override
    460     protected void onStart() {
    461         super.onStart();
    462         // Bind to the service
    463         bindService(new Intent(this, MessengerService.class), mConnection,
    464             Context.BIND_AUTO_CREATE);
    465     }
    466 
    467     &#64;Override
    468     protected void onStop() {
    469         super.onStop();
    470         // Unbind from the service
    471         if (mBound) {
    472             unbindService(mConnection);
    473             mBound = false;
    474         }
    475     }
    476 }
    477 </pre>
    478 
    479 <p>Perhatikan bahwa contoh ini tidak menampilkan cara layanan merespons klien. Jika ingin
    480 layanan merespons, Anda juga perlu membuat {@link android.os.Messenger} di klien. Lalu
    481 saat menerima callback {@link android.content.ServiceConnection#onServiceConnected
    482 onServiceConnected()}, klien akan mengirim {@link android.os.Message} ke layanan yang berisi
    483 {@link android.os.Messenger} klien dalam parameter {@link android.os.Message#replyTo}
    484 metode {@link android.os.Messenger#send send()}.</p>
    485 
    486 <p>Anda bisa melihat contoh cara menyediakan pertukaran pesan dua arah dalam contoh <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code
    487 MessengerService.java}</a> (layanan) dan <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code
    488 MessengerServiceActivities.java}</a> (klien).</p>
    489 
    490 
    491 
    492 
    493 
    494 <h2 id="Binding">Mengikat ke Layanan</h2>
    495 
    496 <p>Komponen-komponen aplikasi (klien) bisa mengikat ke layanan dengan memanggil
    497 {@link android.content.Context#bindService bindService()}. Sistem Android
    498 lalu memanggil metode {@link android.app.Service#onBind
    499 onBind()} layanan, yang menghasilkan {@link android.os.IBinder} untuk berinteraksi dengan layanan.</p>
    500 
    501 <p>Pengikatan ini bersifat asinkron. {@link android.content.Context#bindService
    502 bindService()} segera kembali dan <em>tidak</em> mengembalikan {@link android.os.IBinder} ke
    503 klien. Untuk menerima {@link android.os.IBinder}, klien harus membuat instance {@link
    504 android.content.ServiceConnection} dan meneruskannya ke {@link android.content.Context#bindService
    505 bindService()}. {@link android.content.ServiceConnection} berisi metode callback yang
    506 dipanggil sistem untuk mengirim {@link android.os.IBinder}.</p>
    507 
    508 <p class="note"><strong>Catatan:</strong> Hanya aktivitas, layanan, dan penyedia konten yang bisa mengikat
    509 ke layanan yang&mdash;Anda <strong>tidak bisa</strong> ikat ke layanan dari penerima siaran.</p>
    510 
    511 <p>Jadi, untuk mengikat ke layanan dari klien, Anda harus: </p>
    512 <ol>
    513   <li>Mengimplementasikan {@link android.content.ServiceConnection}.
    514     <p>Implementasi Anda harus mengesampingkan dua metode callback:</p>
    515     <dl>
    516       <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt>
    517         <dd>Sistem memanggil ini untuk mengirim {@link android.os.IBinder} yang dihasilkan oleh
    518 metode {@link android.app.Service#onBind onBind()} layanan.</dd>
    519       <dt>{@link android.content.ServiceConnection#onServiceDisconnected
    520 onServiceDisconnected()}</dt>
    521         <dd>Sistem Android memanggil ini bila koneksi ke layanan putus
    522 tanpa terduga, seperti ketika layanan mengalami crash atau dimatikan. Ini <em>tidak</em> dipanggil ketika
    523 klien melepas ikatan.</dd>
    524     </dl>
    525   </li>
    526   <li>Panggil {@link
    527 android.content.Context#bindService bindService()}, dengan meneruskan implementasi {@link
    528 android.content.ServiceConnection}. </li>
    529   <li>Bila sistem memanggil metode callback {@link android.content.ServiceConnection#onServiceConnected
    530 onServiceConnected()}, Anda bisa mulai membuat panggilan ke layanan, dengan menggunakan
    531 metode yang didefinisikan oleh antarmuka.</li>
    532   <li>Untuk memutus koneksi dari layanan, panggil {@link
    533 android.content.Context#unbindService unbindService()}.
    534     <p>Bila telah dimusnahkan (destroyed), klien Anda akan melepas ikatan dari layanan, namun Anda harus selalu melepas ikatan
    535 bila sudah selesai berinteraksi dengan layanan atau bila aktivitas Anda sedang jeda sehingga layanan bisa
    536 dimatikan saat tidak sedang digunakan. (Waktu yang tepat untuk mengikat dan melepas ikatan dibahas
    537 selengkapnya di bawah ini.)</p>
    538   </li>
    539 </ol>
    540 
    541 <p>Misalnya, cuplikan berikut menghubungkan klien ke layanan yang dibuat di atas dengan
    542 <a href="#Binder">memperluas kelas Binder</a>, sehingga tinggal mengkonversi 
    543 {@link android.os.IBinder} yang dihasilkan ke kelas {@code LocalService} dan meminta instance {@code
    544 LocalService}:</p>
    545 
    546 <pre>
    547 LocalService mService;
    548 private ServiceConnection mConnection = new ServiceConnection() {
    549     // Called when the connection with the service is established
    550     public void onServiceConnected(ComponentName className, IBinder service) {
    551         // Because we have bound to an explicit
    552         // service that is running in our own process, we can
    553         // cast its IBinder to a concrete class and directly access it.
    554         LocalBinder binder = (LocalBinder) service;
    555         mService = binder.getService();
    556         mBound = true;
    557     }
    558 
    559     // Called when the connection with the service disconnects unexpectedly
    560     public void onServiceDisconnected(ComponentName className) {
    561         Log.e(TAG, "onServiceDisconnected");
    562         mBound = false;
    563     }
    564 };
    565 </pre>
    566 
    567 <p>Dengan {@link android.content.ServiceConnection} ini, klien bisa mengikat ke layanan dengan meneruskannya
    568 ke {@link android.content.Context#bindService bindService()}. Misalnya:</p>
    569 
    570 <pre>
    571 Intent intent = new Intent(this, LocalService.class);
    572 bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    573 </pre>
    574 
    575 <ul>
    576   <li>Parameter pertama {@link android.content.Context#bindService bindService()} adalah sebuah 
    577 {@link android.content.Intent} yang secara eksplisit menyebutkan layanan yang akan diikat (walaupun intent
    578 boleh implisit).</li>
    579 <li>Parameter kedua adalah objek {@link android.content.ServiceConnection}.</li>
    580 <li>Parameter ketiga adalah tanda (flag) yang menunjukkan opsi pengikatan. Tanda ini biasanya harus {@link
    581 android.content.Context#BIND_AUTO_CREATE} agar dapat membuat layanan jika belum hidup.
    582 Nilai-nilai lain yang memungkinkan adalah {@link android.content.Context#BIND_DEBUG_UNBIND}
    583 dan {@link android.content.Context#BIND_NOT_FOREGROUND}, atau {@code 0} untuk tidak satu pun.</li>
    584 </ul>
    585 
    586 
    587 <h3>Catatan tambahan</h3>
    588 
    589 <p>Berikut ini beberapa catatan penting tentang mengikat ke layanan:</p>
    590 <ul>
    591   <li>Anda harus selalu menjebak eksepsi {@link android.os.DeadObjectException}, yang dilontarkan
    592 bila koneksi terputus. Inilah satu-satunya eksepsi yang dilontarkan oleh metode jauh.</li>
    593   <li>Objek adalah acuan yang dihitung lintas proses. </li>
    594   <li>Anda biasanya harus memasangkan pengikatan dan pelepasan ikatan selama
    595 memasangkan momen membuat dan menghapus daur hidup klien. Misalnya:
    596     <ul>
    597       <li>Jika Anda hanya perlu berinteraksi dengan layanan saat aktivitas terlihat, Anda
    598 harus mengikat selama {@link android.app.Activity#onStart onStart()} dan melepas ikatan selama {@link
    599 android.app.Activity#onStop onStop()}.</li>
    600       <li>Jika Anda ingin aktivitas menerima tanggapan bahkan saat dihentikan di
    601 latar belakang, Anda bisa mengikat selama {@link android.app.Activity#onCreate onCreate()} dan melepas ikatan
    602 selama {@link android.app.Activity#onDestroy onDestroy()}. Berhati-hatilah karena hal ini menyiratkan aktivitas
    603 Anda perlu menggunakan layanan selama dijalankan (sekalipun di latar belakang), jadi jika
    604 layanan berada dalam proses lain, Anda meningkatkan bobot proses dan semakin besar
    605 kemungkinan sistem akan mematikannya.</li>
    606     </ul>
    607     <p class="note"><strong>Catatan:</strong> Anda biasanya <strong>tidak</strong> boleh mengikat dan melepas ikatan
    608 selama {@link android.app.Activity#onResume onResume()} aktivitas Anda dan {@link
    609 android.app.Activity#onPause onPause()}, karena callback ini terjadi pada setiap transisi daur hidup
    610 dan Anda harus menjaga pemrosesan yang terjadi pada transisi ini tetap minim. Juga, jika
    611 banyak aktivitas dalam aplikasi Anda mengikat ke layanan yang sama dan ada transisi antara
    612 dua aktivitas, layanan bisa dimusnahkan dan dibuat lagi sambil aktivitas saat ini melepas ikatan
    613 (selama jeda) sebelum aktivitas berikutnya mengikat (selama lanjutkan). (Transisi aktivitas ini untuk cara
    614 aktivitas mengoordinasikan daur hidupnya dijelaskan dalam dokumen <a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Aktivitas</a>
    615 .)</p>
    616 </ul>
    617 
    618 <p>Untuk contoh kode selengkapnya, yang menampilkan cara mengikat ke layanan, lihat kelas <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
    619 RemoteService.java}</a> dalam <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
    620 
    621 
    622 
    623 
    624 
    625 <h2 id="Lifecycle">Mengelola Daur Hidup Layanan Terikat</h2>
    626 
    627 <p>Bila layanan dilepas ikatannya dari semua klien, sistem Android akan menghapusnya (kecuali jika layanan juga
    628 dimulai dengan {@link android.app.Service#onStartCommand onStartCommand()}). Dengan demikian, Anda tidak harus
    629 mengelola daur hidup layanan jika layanan itu murni sebuah layanan
    630 terikat&mdash;yang dikelola sistem Android untuk Anda berdasarkan apakah layanan terikat ke klien atau tidak.</p>
    631 
    632 <p>Akan tetapi, Jika Anda memilih untuk mengimplementasikan metode callback {@link android.app.Service#onStartCommand
    633 onStartCommand()}, maka Anda harus menghentikan layanan secara eksplisit, karena layanan
    634 sekarang dianggap telah <em>dimulai</em>. Dalam hal ini, layanan akan berjalan hingga layanan
    635 menghentikan dirinya sendiri dengan {@link android.app.Service#stopSelf()} atau panggilan komponen lain {@link
    636 android.content.Context#stopService stopService()}, terlepas dari apakah layanan terikat ke
    637 klien atau tidak.</p>
    638 
    639 <p>Selain itu, jika layanan Anda telah dimulai dan menerima pengikatan, maka saat sistem memanggil
    640 metode {@link android.app.Service#onUnbind onUnbind()}, Anda bisa memilih untuk mengembalikan
    641 {@code true} jika ingin menerima panggilan ke {@link android.app.Service#onRebind
    642 onRebind()} bila nanti klien mengikat ke layanan (sebagai ganti menerima panggilan ke {@link
    643 android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind
    644 onRebind()} akan menghasilkan void, namun klien tetap menerima {@link android.os.IBinder} dalam callback
    645 {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}.
    646 Di bawah ini adalah gambar 1 yang mengilustrasikan logika untuk jenis daur hidup ini.</p>
    647 
    648 
    649 <img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
    650 <p class="img-caption"><strong>Gambar 1.</strong> Daur hidup untuk layanan yang dimulai
    651 dan juga memungkinkan pengikatan.</p>
    652 
    653 
    654 <p>Untuk informasi selengkapnya tentang daur hidup layanan yang telah dimulai, lihat dokumen <a href="{@docRoot}guide/components/services.html#Lifecycle">Layanan</a>.</p>
    655 
    656 
    657 
    658 
    659