1page.title=Layanan Terikat 2parent.title=Layanan 3parent.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 46komunikasi antarproses (IPC). Layanan terikat biasanya hidup hanya saat melayani 47komponen aplikasi lain dan tidak berjalan di latar belakang terus-menerus.</p> 48 49<p>Dokumen ini menampilkan cara membuat layanan terikat, termasuk cara mengikat 50ke layanan dari komponen aplikasi lain. Akan tetapi, Anda juga harus mengacu dokumen <a href="{@docRoot}guide/components/services.html">Layanan</a> untuk 51informasi tambahan tentang layanan secara umum, seperti cara menyampaikan pemberitahuan dari layanan, mengatur 52layanan 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 58aplikasi lain diikat padanya dan berinteraksi dengannya. Untuk menyediakan pengikatan bagi sebuah 59layanan, Anda harus mengimplementasikan metode callback {@link android.app.Service#onBind onBind()}. Metode ini 60menghasilkan objek {@link android.os.IBinder} yang mendefinisikan antarmuka pemprograman yang 61bisa 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 69dimulai dengan memanggil {@link android.content.Context#startService startService()}, yang memungkinkan 70layanan berjalan terus-menerus, dan juga membolehkan klien untuk mengikat ke layanan dengan memanggil {@link 71android.content.Context#bindService bindService()}. 72 <p>Jika Anda mengizinkan layanan dimulai dan diikat, lalu ketika layanan telah 73dimulai, sistem <em>tidak</em> menghapus layanan ketika semua klien melepas ikatan. Sebagai gantinya, Anda harus 74menghentikan layanan secara eksplisit, dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau {@link 75android.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 79mengimplementasikan keduanya. Misalnya, sebuah pemutar musik bisa merasakan manfaatnya karena layanannya boleh berjalan 80terus-menerus dan juga menyediakan pengikatan. Dengan cara ini, sebuah aktivitas bisa memulai layanan untuk memutar beberapa 81lagu dan musik terus dimainkan sekalipun pengguna meninggalkan aplikasi. Lalu, bila pengguna 82kembali 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 85Terikat</a>, untuk informasi selengkapnya tentang daur hidup layanan saat menambahkan pengikatan ke 86layanan yang sudah dimulai.</p> 87</div> 88</div> 89 90<p>Klien bisa mengikat ke layanan dengan memanggil {@link android.content.Context#bindService 91bindService()}. Bila itu dilakukan, klien harus menyediakan implementasi {@link 92android.content.ServiceConnection}, yang memantau koneksi dengan layanan. Metode {@link 93android.content.Context#bindService bindService()} kembali dengan serta-merta tanpa sebuah nilai, namun 94bila sistem Android membuat koneksi antara klien 95dan layanan, sistem akan memanggil {@link 96android.content.ServiceConnection#onServiceConnected onServiceConnected()} pada {@link 97android.content.ServiceConnection} untuk mengirim {@link android.os.IBinder} yang 98bisa 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 102bila klien pertama mengikat. Sistem lalu memberikan {@link android.os.IBinder} yang sama ke setiap 103klien 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 106layanan juga dimulai oleh {@link android.content.Context#startService startService()}).</p> 107 108<p>Bila Anda mengimplementasikan layanan terikat, yang terpenting adalah mendefinisikan antarmuka 109yang dihasilkan metode callback {@link android.app.Service#onBind onBind()} Anda. Ada sedikit 110cara mendefinisikan antarmuka {@link android.os.IBinder} layanan Anda dan bagian berikut 111akan 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} 118yang menyediakan antarmuka pemrograman yang bisa digunakan klien untuk berinteraksi dengan layanan. Ada 119tiga 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} 125dan menghasilkan instance dari 126{@link android.app.Service#onBind onBind()}. Klien akan menerima {@link android.os.Binder} dan 127bisa menggunakannya untuk mengakses langsung metode publik yang tersedia dalam implementasi {@link android.os.Binder} 128atau bahkan {@link android.app.Service}. 129 <p>Inilah teknik yang lebih disukai bila layanan Anda sekadar pekerja latar belakang untuk aplikasi Anda 130sendiri. Satu-satunya alasan tidak membuat antarmuka dengan cara ini adalah karena 131layanan 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 135antarmuka untuk layanan dengan {@link android.os.Messenger}. Dengan cara ini, layanan 136mendefinisikan {@link android.os.Handler} yang akan merespons aneka tipe objek {@link 137android.os.Message}. {@link android.os.Handler} 138ini adalah dasar bagi {@link android.os.Messenger} yang nanti bisa berbagi {@link android.os.IBinder} 139dengan klien, sehingga memungkinkan klien mengirim perintah ke layanan dengan menggunakan objek {@link 140android.os.Message}. Selain itu, klien bisa mendefinisikan sendiri {@link android.os.Messenger} 141sehingga layanan bisa mengirim balik pesan. 142 <p>Inilah cara termudah melakukan komunikasi antarproses (IPC), karena {@link 143android.os.Messenger} akan mengantre semua permintaan ke dalam satu thread sehingga Anda tidak perlu mendesain 144layanan 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 149primitif yang bisa dipahami dan diarahkan oleh sistem operasi ke berbagai proses untuk melakukan 150IPC. Teknik sebelumnya, dengan menggunakan {@link android.os.Messenger}, sebenarnya berdasarkan AIDL sebagai 151struktur yang mendasarinya. Seperti disebutkan di atas, {@link android.os.Messenger} membuat antrean 152semua permintaan klien dalam satu thread, sehingga layanan akan menerima permintaan satu per satu. Akan tetapi, 153jika ingin layanan Anda menangani beberapa permintaan sekaligus, Anda bisa menggunakan AIDL 154secara langsung. Dalam hal ini, layanan Anda harus mampu multi-thread dan dibuat thread-safe. 155 <p>Untuk menggunakan AIDL secara langsung, Anda harus 156membuat file {@code .aidl} yang mendefinisikan antarmuka pemrograman. Alat Android SDK menggunakan 157file ini untuk menghasilkan kelas abstrak yang mengimplementasikan antarmuka dan menangani IPC, yang nanti 158bisa 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 163membuat layanan terikat, karena hal itu mungkin memerlukan kemampuan multi-thread dan 164bisa mengakibatkan implementasi yang lebih rumit. Dengan demikian, AIDL tidak cocok untuk sebagian besar aplikasi 165dan dokumen ini tidak membahas cara menggunakannya untuk layanan Anda. Jika Anda yakin perlu 166menggunakan 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, 175maka Anda bisa mengimplementasikan kelas {@link android.os.Binder} Anda sendiri yang memberi klien Anda 176akses 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 179aplikasi dan proses yang sama, suatu kondisi yang paling umum. Misalnya, cara ini sangat cocok untuk sebuah aplikasi musik 180yang perlu mengikat aktivitas ke layanannya sendiri, yakni memutar musik di 181latar 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 189bisa dipanggil klien</li> 190 <li>atau, menghasilkan instance kelas lain yang host-nya di layanan dengan metode publik yang 191bisa dipanggil klien</li> 192 </ul> 193 <li>Hasilkan instance {@link android.os.Binder} ini dari metode callback {@link 194android.app.Service#onBind onBind()}.</li> 195 <li>Di klien, terima {@link android.os.Binder} dari metode callback {@link 196android.content.ServiceConnection#onServiceConnected onServiceConnected()} dan 197buat 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 201adalah agar klien bisa mengkonversi objek yang dihasilkan dan memanggil API-nya dengan benar. Layanan 202dan klien juga harus berada dalam proses yang sama, karena teknik ini tidak melakukan 203pengarahan (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 206implementasi {@link android.os.Binder}:</p> 207 208<pre> 209public 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 @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 239instance {@code LocalService} saat ini. Cara ini memungkinkan klien memanggil metode publik dalam 240layanan. 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()} 243bila tombol diklik:</p> 244 245<pre> 246public class BindingActivity extends Activity { 247 LocalService mService; 248 boolean mBound = false; 249 250 @Override 251 protected void onCreate(Bundle savedInstanceState) { 252 super.onCreate(savedInstanceState); 253 setContentView(R.layout.main); 254 } 255 256 @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 @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 @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 @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 308android.content.ServiceConnection#onServiceConnected onServiceConnected()}. Bagian 309berikut 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, 312namun 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 315LocalService.java}</a> dan kelas <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code 316LocalServiceActivities.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 328lebih sederhana daripada mengimplementasikannya dengan AIDL, karena {@link android.os.Messenger} mengantre 329semua panggilan ke layanan, sementara antarmuka AIDL murni mengirim permintaan serentak ke 330layanan, yang nanti harus menangani multi-threading.</p> 331 <p>Untuk sebagian besar aplikasi, layanan tidak perlu melakukan multi-threading, jadi dengan menggunakan {@link 332android.os.Messenger} memungkinkan layanan menangani panggilan satu per satu. Jika 333layanan 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 339Anda 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 345panggilan 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 349dikembalikan 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 352objek {@link android.os.Message} ke layanan.</li> 353 <li>Layanan menerima setiap {@link android.os.Message} dalam {@link 354android.os.Handler}—secara spesifik, dalam metode {@link android.os.Handler#handleMessage 355handleMessage()}.</li> 356</ul> 357 358 359<p>Dengan cara ini, tidak ada "metode" untuk dipanggil klien pada layanan. Sebagai gantinya, 360klien 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> 366public 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 @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 @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} 405yang 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 408android.os.IBinder} yang dihasilkan layanan dan mengirim pesan menggunakan {@link 409android.os.Messenger#send send()}. Misalnya, berikut ini adalah aktivitas sederhana yang mengikat ke 410layanan dan mengirim pesan {@code MSG_SAY_HELLO} ke layanan:</p> 411 412<pre> 413public 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 @Override 454 protected void onCreate(Bundle savedInstanceState) { 455 super.onCreate(savedInstanceState); 456 setContentView(R.layout.main); 457 } 458 459 @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 @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 480layanan merespons, Anda juga perlu membuat {@link android.os.Messenger} di klien. Lalu 481saat menerima callback {@link android.content.ServiceConnection#onServiceConnected 482onServiceConnected()}, klien akan mengirim {@link android.os.Message} ke layanan yang berisi 483{@link android.os.Messenger} klien dalam parameter {@link android.os.Message#replyTo} 484metode {@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 487MessengerService.java}</a> (layanan) dan <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code 488MessengerServiceActivities.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 498lalu memanggil metode {@link android.app.Service#onBind 499onBind()} layanan, yang menghasilkan {@link android.os.IBinder} untuk berinteraksi dengan layanan.</p> 500 501<p>Pengikatan ini bersifat asinkron. {@link android.content.Context#bindService 502bindService()} segera kembali dan <em>tidak</em> mengembalikan {@link android.os.IBinder} ke 503klien. Untuk menerima {@link android.os.IBinder}, klien harus membuat instance {@link 504android.content.ServiceConnection} dan meneruskannya ke {@link android.content.Context#bindService 505bindService()}. {@link android.content.ServiceConnection} berisi metode callback yang 506dipanggil 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 509ke layanan yang—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 518metode {@link android.app.Service#onBind onBind()} layanan.</dd> 519 <dt>{@link android.content.ServiceConnection#onServiceDisconnected 520onServiceDisconnected()}</dt> 521 <dd>Sistem Android memanggil ini bila koneksi ke layanan putus 522tanpa terduga, seperti ketika layanan mengalami crash atau dimatikan. Ini <em>tidak</em> dipanggil ketika 523klien melepas ikatan.</dd> 524 </dl> 525 </li> 526 <li>Panggil {@link 527android.content.Context#bindService bindService()}, dengan meneruskan implementasi {@link 528android.content.ServiceConnection}. </li> 529 <li>Bila sistem memanggil metode callback {@link android.content.ServiceConnection#onServiceConnected 530onServiceConnected()}, Anda bisa mulai membuat panggilan ke layanan, dengan menggunakan 531metode yang didefinisikan oleh antarmuka.</li> 532 <li>Untuk memutus koneksi dari layanan, panggil {@link 533android.content.Context#unbindService unbindService()}. 534 <p>Bila telah dimusnahkan (destroyed), klien Anda akan melepas ikatan dari layanan, namun Anda harus selalu melepas ikatan 535bila sudah selesai berinteraksi dengan layanan atau bila aktivitas Anda sedang jeda sehingga layanan bisa 536dimatikan saat tidak sedang digunakan. (Waktu yang tepat untuk mengikat dan melepas ikatan dibahas 537selengkapnya 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 544LocalService}:</p> 545 546<pre> 547LocalService mService; 548private 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 568ke {@link android.content.Context#bindService bindService()}. Misalnya:</p> 569 570<pre> 571Intent intent = new Intent(this, LocalService.class); 572bindService(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 578boleh 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 581android.content.Context#BIND_AUTO_CREATE} agar dapat membuat layanan jika belum hidup. 582Nilai-nilai lain yang memungkinkan adalah {@link android.content.Context#BIND_DEBUG_UNBIND} 583dan {@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 592bila 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 595memasangkan momen membuat dan menghapus daur hidup klien. Misalnya: 596 <ul> 597 <li>Jika Anda hanya perlu berinteraksi dengan layanan saat aktivitas terlihat, Anda 598harus mengikat selama {@link android.app.Activity#onStart onStart()} dan melepas ikatan selama {@link 599android.app.Activity#onStop onStop()}.</li> 600 <li>Jika Anda ingin aktivitas menerima tanggapan bahkan saat dihentikan di 601latar belakang, Anda bisa mengikat selama {@link android.app.Activity#onCreate onCreate()} dan melepas ikatan 602selama {@link android.app.Activity#onDestroy onDestroy()}. Berhati-hatilah karena hal ini menyiratkan aktivitas 603Anda perlu menggunakan layanan selama dijalankan (sekalipun di latar belakang), jadi jika 604layanan berada dalam proses lain, Anda meningkatkan bobot proses dan semakin besar 605kemungkinan sistem akan mematikannya.</li> 606 </ul> 607 <p class="note"><strong>Catatan:</strong> Anda biasanya <strong>tidak</strong> boleh mengikat dan melepas ikatan 608selama {@link android.app.Activity#onResume onResume()} aktivitas Anda dan {@link 609android.app.Activity#onPause onPause()}, karena callback ini terjadi pada setiap transisi daur hidup 610dan Anda harus menjaga pemrosesan yang terjadi pada transisi ini tetap minim. Juga, jika 611banyak aktivitas dalam aplikasi Anda mengikat ke layanan yang sama dan ada transisi antara 612dua 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 614aktivitas 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 619RemoteService.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 628dimulai dengan {@link android.app.Service#onStartCommand onStartCommand()}). Dengan demikian, Anda tidak harus 629mengelola daur hidup layanan jika layanan itu murni sebuah layanan 630terikat—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 633onStartCommand()}, maka Anda harus menghentikan layanan secara eksplisit, karena layanan 634sekarang dianggap telah <em>dimulai</em>. Dalam hal ini, layanan akan berjalan hingga layanan 635menghentikan dirinya sendiri dengan {@link android.app.Service#stopSelf()} atau panggilan komponen lain {@link 636android.content.Context#stopService stopService()}, terlepas dari apakah layanan terikat ke 637klien atau tidak.</p> 638 639<p>Selain itu, jika layanan Anda telah dimulai dan menerima pengikatan, maka saat sistem memanggil 640metode {@link android.app.Service#onUnbind onUnbind()}, Anda bisa memilih untuk mengembalikan 641{@code true} jika ingin menerima panggilan ke {@link android.app.Service#onRebind 642onRebind()} bila nanti klien mengikat ke layanan (sebagai ganti menerima panggilan ke {@link 643android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind 644onRebind()} akan menghasilkan void, namun klien tetap menerima {@link android.os.IBinder} dalam callback 645{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}. 646Di 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 651dan 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