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    &#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
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    &#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
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}&mdash;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        &#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}
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    &#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
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&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
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&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
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