1page.title=Layanan
2@jd:body
3
4<div id="qv-wrapper">
5<ol id="qv">
6<h2>Dalam dokumen ini</h2>
7<ol>
8<li><a href="#Basics">Dasar-Dasar</a></li>
9<ol>
10  <li><a href="#Declaring">Mendeklarasikan layanan dalam manifes</a></li>
11</ol>
12<li><a href="#CreatingAService">Membuat Layanan yang Sudah Dimulai</a>
13  <ol>
14    <li><a href="#ExtendingIntentService">Memperluas kelas IntentService</a></li>
15    <li><a href="#ExtendingService">Memperluas kelas Layanan</a></li>
16    <li><a href="#StartingAService">Memulai layanan</a></li>
17    <li><a href="#Stopping">Menghentikan layanan</a></li>
18  </ol>
19</li>
20<li><a href="#CreatingBoundService">Membuat Layanan Terikat</a></li>
21<li><a href="#Notifications">Mengirim Pemberitahuan ke Pengguna</a></li>
22<li><a href="#Foreground">Menjalankan Layanan di Latar Depan</a></li>
23<li><a href="#Lifecycle">Mengelola Daur Hidup Layanan</a>
24<ol>
25  <li><a href="#LifecycleCallbacks">Mengimplementasikan callback daur hidup</a></li>
26</ol>
27</li>
28</ol>
29
30<h2>Kelas-kelas utama</h2>
31<ol>
32  <li>{@link android.app.Service}</li>
33  <li>{@link android.app.IntentService}</li>
34</ol>
35
36<h2>Contoh</h2>
37<ol>
38  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code
39      ServiceStartArguments}</a></li>
40  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
41      LocalService}</a></li>
42</ol>
43
44<h2>Lihat juga</h2>
45<ol>
46<li><a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a></li>
47</ol>
48
49</div>
50
51
52<p>{@link android.app.Service} adalah sebuah komponen aplikasi yang bisa melakukan
53operasi yang berjalan lama di latar belakang dan tidak menyediakan antarmuka pengguna. Komponen
54aplikasi lain bisa memulai layanan dan komponen aplikasi tersebut akan terus berjalan
55di latar belakang walaupun pengguna beralih ke aplikasi lain. Selain itu, komponen bisa mengikat ke layanan
56untuk berinteraksi dengannya dan bahkan melakukan komunikasi antarproses (IPC). Misalnya, layanan mungkin
57menangani transaksi jaringan, memutar musik, melakukan file I/O, atau berinteraksi dengan penyedia konten
58dari latar belakang.</p>
59
60<p>Ada dua bentuk dasar layanan:</p>
61
62<dl>
63  <dt>Sudah Dimulai</dt>
64  <dd>Layanan "sudah dimulai" bila komponen aplikasi (misalnya aktivitas) memulainya dengan
65memanggil {@link android.content.Context#startService startService()}. Sesudah dimulai, layanan
66bisa berjalan terus-menerus di latar belakang walaupun komponen yang memulainya telah dimusnahkan. Biasanya,
67layanan yang sudah dimulai akan melakukan operasi tunggal dan tidak mengembalikan hasil ke pemanggilnya.
68Misalnya, layanan bisa mengunduh atau mengunggah file melalui jaringan. Bila operasi selesai,
69layanan seharusnya berhenti sendiri.</dd>
70  <dt>Terikat</dt>
71  <dd>Layanan "terikat" bila komponen aplikasi mengikat kepadanya dengan memanggil {@link
72android.content.Context#bindService bindService()}. Layanan terikat menawarkan antarmuka
73klien-server yang memungkinkan komponen berinteraksi dengan layanan tersebut, mengirim permintaan, mendapatkan hasil dan bahkan
74melakukannya pada sejumlah proses dengan komunikasi antarproses (IPC). Layanan terikat hanya berjalan selama
75ada komponen aplikasi lain yang terikat padanya. Sejumlah komponen bisa terikat pada layanan secara bersamaan,
76namun bila semuanya melepas ikatan, layanan tersebut akan dimusnahkan.</dd>
77</dl>
78
79<p>Walaupun dokumentasi ini secara umum membahas kedua jenis layanan secara terpisah, layanan
80Anda bisa menggunakan keduanya&mdash;layanan bisa dimulai (untuk berjalan terus-menerus) sekaligus memungkinkan pengikatan.
81Cukup mengimplementasikan dua metode callback: {@link
82android.app.Service#onStartCommand onStartCommand()} untuk memungkinkan komponen memulainya dan {@link
83android.app.Service#onBind onBind()} untuk memungkinkan pengikatan.</p>
84
85<p>Apakah aplikasi Anda sudah dimulai, terikat, atau keduanya, semua komponen aplikasi
86bisa menggunakan layanan (bahkan dari aplikasi terpisah), demikian pula semua komponen bisa menggunakan
87suatu aktivitas&mdash;dengan memulainya dengan {@link android.content.Intent}. Akan tetapi, Anda bisa mendeklarasikan
88layanan sebagai privat, pada file manifes, dan memblokir akses dari aplikasi lain. Hal ini
89dibahas selengkapnya di bagian tentang <a href="#Declaring">Mendeklarasikan layanan dalam
90manifes</a>.</p>
91
92<p class="caution"><strong>Perhatian:</strong> Layanan berjalan di
93thread utama proses yang menjadi host-nya&mdash;layanan <strong>tidak</strong> membuat thread-nya sendiri
94dan <strong>tidak</strong> berjalan pada proses terpisah (kecuali bila Anda tentukan demikian). Artinya,
95jika layanan Anda akan melakukan pekerjaan yang membutuhkan tenaga CPU besar atau operasi yang memblokir (seperti
96pemutaran MP3 atau jaringan), Anda perlu membuat thread baru dalam layanan untuk melakukan pekerjaan tersebut. Dengan menggunakan
97thread terpisah, Anda mengurangi risiko terjadinya kesalahan Aplikasi Tidak Merespons (Application Not Responding/ANR) dan
98thread utama aplikasi bisa tetap dikhususkan pada interaksi pengguna dengan aktivitas Anda.</p>
99
100
101<h2 id="Basics">Dasar-Dasar</h2>
102
103<div class="sidebox-wrapper">
104<div class="sidebox">
105  <h3>Haruskah menggunakan layanan atau thread?</h3>
106  <p>Layanan sekadar komponen yang bisa berjalan di latar belakang walaupun pengguna sedang tidak
107berinteraksi dengan aplikasi Anda. Sehingga, Anda harus membuat layanan bila memang itu
108yang dibutuhkan.</p>
109  <p>Bila Anda perlu melakukan pekerjaan di luar thread utama, namun hanya bila pengguna sedang berinteraksi
110dengan aplikasi, maka Anda harus membuat thread baru sebagai ganti layanan baru. Misalnya,
111bila Anda ingin memutar musik, namun hanya saat aktivitas Anda berjalan, Anda bisa membuat
112thread dalam {@link android.app.Activity#onCreate onCreate()}, mulai menjalankannya di {@link
113android.app.Activity#onStart onStart()}, kemudian menghentikannya di {@link android.app.Activity#onStop
114onStop()}. Pertimbangkan juga untuk menggunakan {@link android.os.AsyncTask} atau {@link android.os.HandlerThread},
115sebagai ganti kelas {@link java.lang.Thread} yang lazim digunakan. Lihat dokumen <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">Proses dan
116Threading</a> untuk informasi selengkapnya tentang thread.</p>
117  <p>Ingatlah jika menggunakan layanan, layanan tersebut tetap berjalan di thread utama aplikasi Anda secara
118default, jadi Anda harus tetap membuat thread baru dalam layanan bila layanan tersebut melakukan operasi yang intensif
119atau operasi yang memblokir.</p>
120</div>
121</div>
122
123<p>Untuk membuat layanan, Anda harus membuat subkelas {@link android.app.Service} (atau
124salah satu dari subkelasnya yang ada). Dalam implementasi, Anda perlu mengesampingkan sebagian metode callback yang
125menangani aspek utama daur hidup layanan dan memberikan mekanisme bagi komponen untuk mengikat
126pada layanan, bila dibutuhkan. Metode callback terpenting yang perlu Anda kesampingkan adalah:</p>
127
128<dl>
129  <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
130    <dd>Sistem akan memanggil metode ini bila komponen lain, misalnya aktivitas,
131meminta dimulainya layanan, dengan memanggil {@link android.content.Context#startService
132startService()}. Setelah metode ini dieksekusi, layanan akan dimulai dan bisa berjalan di
133latar belakang terus-menerus. Jika mengimplementasikan ini, Anda bertanggung jawab menghentikan layanan bila
134bila pekerjaannya selesai, dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau {@link
135android.content.Context#stopService stopService()}. (Jika hanya ingin menyediakan pengikatan, Anda tidak
136perlu mengimplementasikan metode ini.)</dd>
137  <dt>{@link android.app.Service#onBind onBind()}</dt>
138    <dd>Sistem akan memanggil metode ini bila komponen lain ingin mengikat pada
139layanan (misalnya untuk melakukan RPC), dengan memanggil {@link android.content.Context#bindService
140bindService()}. Dalam mengimplementasikan metode ini, Anda harus menyediakan antarmuka yang digunakan
141klien untuk berkomunikasi dengan layanan, dengan mengembalikan {@link android.os.IBinder}. Anda harus selalu
142mengimplementasikan metode ini, namun jika tidak ingin mengizinkan pengikatan, Anda perlu mengembalikan null.</dd>
143  <dt>{@link android.app.Service#onCreate()}</dt>
144    <dd>Sistem memanggil metode ini bila layanan dibuat untuk pertama kalinya, untuk melakukan prosedur
145penyiapan satu kali (sebelum memanggil {@link android.app.Service#onStartCommand onStartCommand()} atau
146{@link android.app.Service#onBind onBind()}). Bila layanan sudah berjalan, metode ini tidak
147dipanggil.</dd>
148  <dt>{@link android.app.Service#onDestroy()}</dt>
149    <dd>Sistem memanggil metode ini bila layanan tidak lagi digunakan dan sedang dimusnahkan.
150Layanan Anda perlu mengimplementasikannya untuk membersihkan sumber daya seperti thread, listener
151terdaftar, penerima, dll. Ini adalah panggilan terakhir yang diterima layanan.</dd>
152</dl>
153
154<p>Bila komponen memulai layanan dengan memanggil {@link
155android.content.Context#startService startService()} (yang menyebabkan panggilan ke {@link
156android.app.Service#onStartCommand onStartCommand()}), maka layanan
157terus berjalan hingga terhenti sendiri dengan {@link android.app.Service#stopSelf()} atau bila komponen
158lain menghentikannya dengan memanggil {@link android.content.Context#stopService stopService()}.</p>
159
160<p>Bila komponen memanggil
161{@link android.content.Context#bindService bindService()} untuk membuat layanan (dan {@link
162android.app.Service#onStartCommand onStartCommand()} <em>tidak</em> dipanggil), maka layanan hanya berjalan
163selama komponen terikat kepadanya. Setelah layanan dilepas ikatannya dari semua klien,
164sistem akan menghancurkannya.</p>
165
166<p>Sistem Android akan menghentikan paksa layanan hanya bila memori tinggal sedikit dan sistem harus memulihkan
167sumber daya sistem untuk aktivitas yang mendapatkan fokus pengguna. Jika layanan terikat pada suatu aktivitas yang mendapatkan
168fokus pengguna, layanan tersebut lebih kecil kemungkinannya untuk dimatikan, dan jika layanan dideklarasikan untuk <a href="#Foreground">berjalan di latar depan</a> (akan dibahas kemudian), maka sudah hampir pasti ia tidak akan dimatikan.
169Sebaliknya, bila layanan sudah dimulai dan berjalan lama, maka sistem akan menurunkan posisinya
170dalam daftar tugas latar belakang seiring waktu dan layanan akan sangat rentan untuk
171dimatikan&mdash;bila layanan Anda dimulai, maka Anda harus mendesainnya agar bisa menangani restart
172oleh sistem dengan baik. Jika sistem mematikan layanan Anda, layanan akan dimulai kembali begitu sumber daya
173kembali tersedia (tetapi ini juga bergantung pada nilai yang Anda kembalikan dari {@link
174android.app.Service#onStartCommand onStartCommand()}, sebagaimana akan dibahas nanti). Untuk informasi selengkapnya
175tentang kapan sistem mungkin akan memusnahkan layanan, lihat dokumen
176<a href="{@docRoot}guide/components/processes-and-threads.html">Proses dan Threading</a>.</p>
177
178<p>Dalam bagian selanjutnya, Anda akan melihat bagaimana membuat masing-masing tipe layanan dan cara menggunakannya
179dari komponen aplikasi lain.</p>
180
181
182
183<h3 id="Declaring">Mendeklarasikan layanan dalam manifes</h3>
184
185<p>Sebagaimana aktivitas (dan komponen lainnya), Anda harus mendeklarasikan semua layanan dalam file manifes
186aplikasi Anda.</p>
187
188<p>Untuk mendeklarasikan layanan Anda, tambahkan sebuah elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a>
189sebagai anak
190elemen <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>. Misalnya:</p>
191
192<pre>
193&lt;manifest ... &gt;
194  ...
195  &lt;application ... &gt;
196      &lt;service android:name=".ExampleService" /&gt;
197      ...
198  &lt;/application&gt;
199&lt;/manifest&gt;
200</pre>
201
202<p>Lihat acuan elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a>
203untuk informasi selengkapnya tentang cara mendeklarasikan layanan Anda dalam manifes.</p>
204
205<p>Ada atribut lain yang bisa Anda sertakan dalam elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> untuk
206mendefinisikan properti seperti izin yang dibutuhkan untuk memulai layanan dan proses
207tempat berjalannya layanan. <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a> adalah satu-satunya atribut yang diperlukan
208&mdash;atribut tersebut menetapkan nama kelas layanan. Setelah
209mempublikasikan aplikasi, Anda tidak boleh mengubah nama ini, karena jika melakukannya, Anda bisa merusak
210kode karena dependensi terhadap intent eksplisit untuk memulai atau mengikat layanan (bacalah posting blog berjudul <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Things
211That Cannot Change</a>).
212
213<p>Untuk memastikan aplikasi Anda aman, <strong>selalu gunakan intent eksplisit saat memulai atau mengikat
214{@link android.app.Service} Anda</strong> dan jangan mendeklarasikan filter intent untuk layanan. Jika
215Anda perlu membiarkan adanya ambiguitas tentang layanan mana yang dimulai, Anda bisa
216menyediakan filter intent bagi layanan dan tidak memasukkan nama komponen pada {@link
217android.content.Intent}, namun Anda juga harus menyesuaikan paket bagi intent tersebut dengan {@link
218android.content.Intent#setPackage setPackage()}, yang memberikan klarifikasi memadai bagi
219target layanan.</p>
220
221<p>Anda juga bisa memastikan layanan tersedia hanya bagi aplikasi Anda dengan
222menyertakan atribut <a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
223dan mengaturnya ke {@code "false"}. Hal ini efektif menghentikan aplikasi lain agar tidak memulai
224layanan Anda, bahkan saat menggunakan intent eksplisit.</p>
225
226
227
228
229<h2 id="CreatingStartedService">Membuat Layanan yang Sudah Dimulai</h2>
230
231<p>Layanan yang sudah dimulai adalah layanan yang dimulai komponen lain dengan memanggil {@link
232android.content.Context#startService startService()}, yang menyebabkan panggilan ke metode
233{@link android.app.Service#onStartCommand onStartCommand()} layanan.</p>
234
235<p>Bila layanan sudah dimulai, layanan tersebut memiliki daur hidup yang tidak bergantung pada
236komponen yang memulainya dan bisa berjalan terus-menerus di latar belakang walaupun
237komponen yang memulainya dimusnahkan. Dengan sendirinya, layanan akan berhenti sendiri bila pekerjaannya
238selesai dengan memanggil {@link android.app.Service#stopSelf stopSelf()}, atau komponen lain bisa menghentikannya
239dengan memanggil {@link android.content.Context#stopService stopService()}.</p>
240
241<p>Komponen aplikasi seperti aktivitas bisa memulai layanan dengan memanggil {@link
242android.content.Context#startService startService()} dan meneruskan {@link android.content.Intent}
243yang menetapkan layanan dan menyertakan data untuk digunakan layanan. Layanan menerima
244{@link android.content.Intent} ini dalam metode {@link android.app.Service#onStartCommand
245onStartCommand()}.</p>
246
247<p>Sebagai contoh, anggaplah aktivitas perlu menyimpan data ke database online. Aktivitas tersebut bisa
248memulai layanan pendamping dan mengiriminya data untuk disimpan dengan meneruskan intent ke {@link
249android.content.Context#startService startService()}. Layanan akan menerima intent dalam {@link
250android.app.Service#onStartCommand onStartCommand()}, menghubungkan ke Internet dan melakukan
251transaksi database. Bila transaksi selesai, layanan akan berhenti sendiri dan
252dimusnahkan.</p>
253
254<p class="caution"><strong>Perhatian:</strong> Layanan berjalan dalam proses yang sama dengan aplikasi
255tempatnya dideklarasikan dan dalam thread utama aplikasi tersebut, secara default. Jadi, bila layanan Anda
256melakukan operasi yang intensif atau operasi pemblokiran saat pengguna berinteraksi dengan aktivitas dari
257aplikasi yang sama, layanan akan memperlambat kinerja aktivitas. Agar tidak memengaruhi
258kinerja aplikasi, Anda harus memulai thread baru di dalam layanan.</p>
259
260<p>Biasanya, ada dua kelas yang bisa Anda perluas untuk membuat layanan yang sudah dimulai:</p>
261<dl>
262  <dt>{@link android.app.Service}</dt>
263  <dd>Ini adalah kelas dasar untuk semua layanan. Bila memperluas kelas ini, Anda perlu
264membuat thread baru sebagai tempat melaksanakan semua pekerjaan layanan tersebut, karena layanan
265menggunakan thread utama aplikasi Anda secara default, dan hal ini bisa memperlambat
266kinerja aktivitas yang dijalankan aplikasi Anda.</dd>
267  <dt>{@link android.app.IntentService}</dt>
268  <dd>Ini adalah subkelas {@link android.app.Service} yang menggunakan thread pekerja untuk menangani
269semua permintaan memulai, satu per satu. Ini adalah pilihan terbaik jika Anda tidak mengharuskan layanan
270menangani beberapa permintaan sekaligus. Anda cukup mengimplementasikan {@link
271android.app.IntentService#onHandleIntent onHandleIntent()}, yang menerima intent untuk setiap
272permintaan memulai agar bisa melakukan pekerjaan latar belakang.</dd>
273</dl>
274
275<p>Bagian selanjutnya membahas cara mengimplementasikan layanan Anda menggunakan
276salah satu dari kelas-kelas ini.</p>
277
278
279<h3 id="ExtendingIntentService">Memperluas kelas IntentService</h3>
280
281<p>Mengingat kebanyakan layanan yang sudah dimulai tidak perlu menangani beberapa permintaan
282sekaligus (yang bisa berupa skenario multi-threading berbahaya), mungkin Anda sebaiknya mengimplementasikan
283layanan menggunakan kelas {@link android.app.IntentService}.</p>
284
285<p>Berikut ini yang dilakukan {@link android.app.IntentService}:</p>
286
287<ul>
288  <li>Membuat thread pekerja default yang menjalankan semua intent yang disampaikan ke {@link
289android.app.Service#onStartCommand onStartCommand()} terpisah dari thread utama aplikasi
290Anda.</li>
291  <li>Membuat antrean pekerjaan yang meneruskan intent satu per satu ke implementasi {@link
292android.app.IntentService#onHandleIntent onHandleIntent()}, sehingga Anda tidak perlu
293mengkhawatirkan multi-threading.</li>
294  <li>Menghentikan layanan setelah semua permintaan memulai telah ditangani, jadi Anda tidak perlu memanggil
295{@link android.app.Service#stopSelf}.</li>
296  <li>Menyediakan implementasi default {@link android.app.IntentService#onBind onBind()} yang
297mengembalikan null.</li>
298  <li>Menyediakan implementasi default {@link android.app.IntentService#onStartCommand
299onStartCommand()} yang mengirimkan intent ke antrean pekerjaan kemudian ke implementasi {@link
300android.app.IntentService#onHandleIntent onHandleIntent()} Anda.</li>
301</ul>
302
303<p>Oleh karena itu, Anda hanya perlu mengimplementasikan {@link
304android.app.IntentService#onHandleIntent onHandleIntent()} untuk melakukan pekerjaan yang diberikan oleh
305klien. (Akan tetapi, Anda juga perlu menyediakan konstruktor kecil bagi layanan.)</p>
306
307<p>Berikut ini contoh implementasi {@link android.app.IntentService}:</p>
308
309<pre>
310public class HelloIntentService extends IntentService {
311
312  /**
313   * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
314   * constructor with a name for the worker thread.
315   */
316  public HelloIntentService() {
317      super("HelloIntentService");
318  }
319
320  /**
321   * The IntentService calls this method from the default worker thread with
322   * the intent that started the service. When this method returns, IntentService
323   * stops the service, as appropriate.
324   */
325  &#64;Override
326  protected void onHandleIntent(Intent intent) {
327      // Normally we would do some work here, like download a file.
328      // For our sample, we just sleep for 5 seconds.
329      long endTime = System.currentTimeMillis() + 5*1000;
330      while (System.currentTimeMillis() &lt; endTime) {
331          synchronized (this) {
332              try {
333                  wait(endTime - System.currentTimeMillis());
334              } catch (Exception e) {
335              }
336          }
337      }
338  }
339}
340</pre>
341
342<p>Anda hanya memerlukan: konstruktor dan implementasi {@link
343android.app.IntentService#onHandleIntent onHandleIntent()}.</p>
344
345<p>Jika Anda memutuskan untuk juga mengesampingkan metode callback lain, seperti {@link
346android.app.IntentService#onCreate onCreate()}, {@link
347android.app.IntentService#onStartCommand onStartCommand()}, atau {@link
348android.app.IntentService#onDestroy onDestroy()}, pastikan memanggil implementasi super, sehingga
349{@link android.app.IntentService} bisa menangani hidup thread pekerja dengan baik.</p>
350
351<p>Misalnya, {@link android.app.IntentService#onStartCommand onStartCommand()} harus mengembalikan
352implementasi default (yang merupakan cara penyampaian intent ke {@link
353android.app.IntentService#onHandleIntent onHandleIntent()}):</p>
354
355<pre>
356&#64;Override
357public int onStartCommand(Intent intent, int flags, int startId) {
358    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
359    return super.onStartCommand(intent,flags,startId);
360}
361</pre>
362
363<p>Selain {@link android.app.IntentService#onHandleIntent onHandleIntent()}, satu-satunya metode lain
364yang tidak mengharuskan Anda memanggil super kelas adalah {@link android.app.IntentService#onBind
365onBind()} (namun Anda hanya perlu mengimplementasikannya bila layanan mengizinkan pengikatan).</p>
366
367<p>Dalam bagian berikutnya, Anda akan melihat bagaimana layanan serupa diimplementasikan saat
368memperluas kelas {@link android.app.Service} basis, yang membutuhkan kode lebih banyak lagi, namun mungkin
369cocok jika Anda perlu menangani beberapa permintaan memulai sekaligus.</p>
370
371
372<h3 id="ExtendingService">Memperluas kelas Layanan</h3>
373
374<p>Seperti telah Anda lihat di bagian sebelumnya, menggunakan {@link android.app.IntentService} membuat
375implementasi layanan yang sudah dimulai jadi sangat sederhana. Namun, bila Anda mengharuskan layanan untuk
376melakukan multi-threading (sebagai ganti memproses permintaan memulai melalui antrean pekerjaan), maka Anda
377bisa memperluas kelas {@link android.app.Service} untuk menangani masing-masing intent.</p>
378
379<p>Sebagai perbandingan, contoh kode berikut ini adalah implementasi kelas {@link
380android.app.Service} yang melakukan pekerjaan yang persis sama dengan contoh di atas menggunakan {@link
381android.app.IntentService}. Artinya, untuk setiap permintaan memulai, kode tersebut akan menggunakan thread pekerja
382untuk melakukan pekerjaan dan memproses permintaan satu per satu.</p>
383
384<pre>
385public class HelloService extends Service {
386  private Looper mServiceLooper;
387  private ServiceHandler mServiceHandler;
388
389  // Handler that receives messages from the thread
390  private final class ServiceHandler extends Handler {
391      public ServiceHandler(Looper looper) {
392          super(looper);
393      }
394      &#64;Override
395      public void handleMessage(Message msg) {
396          // Normally we would do some work here, like download a file.
397          // For our sample, we just sleep for 5 seconds.
398          long endTime = System.currentTimeMillis() + 5*1000;
399          while (System.currentTimeMillis() &lt; endTime) {
400              synchronized (this) {
401                  try {
402                      wait(endTime - System.currentTimeMillis());
403                  } catch (Exception e) {
404                  }
405              }
406          }
407          // Stop the service using the startId, so that we don't stop
408          // the service in the middle of handling another job
409          stopSelf(msg.arg1);
410      }
411  }
412
413  &#64;Override
414  public void onCreate() {
415    // Start up the thread running the service.  Note that we create a
416    // separate thread because the service normally runs in the process's
417    // main thread, which we don't want to block.  We also make it
418    // background priority so CPU-intensive work will not disrupt our UI.
419    HandlerThread thread = new HandlerThread("ServiceStartArguments",
420            Process.THREAD_PRIORITY_BACKGROUND);
421    thread.start();
422
423    // Get the HandlerThread's Looper and use it for our Handler
424    mServiceLooper = thread.getLooper();
425    mServiceHandler = new ServiceHandler(mServiceLooper);
426  }
427
428  &#64;Override
429  public int onStartCommand(Intent intent, int flags, int startId) {
430      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
431
432      // For each start request, send a message to start a job and deliver the
433      // start ID so we know which request we're stopping when we finish the job
434      Message msg = mServiceHandler.obtainMessage();
435      msg.arg1 = startId;
436      mServiceHandler.sendMessage(msg);
437
438      // If we get killed, after returning from here, restart
439      return START_STICKY;
440  }
441
442  &#64;Override
443  public IBinder onBind(Intent intent) {
444      // We don't provide binding, so return null
445      return null;
446  }
447
448  &#64;Override
449  public void onDestroy() {
450    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
451  }
452}
453</pre>
454
455<p>Seperti yang bisa Anda lihat, ini membutuhkan lebih banyak pekerjaan daripada menggunakan {@link android.app.IntentService}.</p>
456
457<p>Akan tetapi, karena Anda menangani sendiri setiap panggilan ke {@link android.app.Service#onStartCommand
458onStartCommand()}, Anda bisa melakukan beberapa permintaan sekaligus. Itu bukan yang
459dilakukan contoh ini, namun jika itu yang diinginkan, Anda bisa membuat thread baru untuk setiap
460permintaan dan langsung menjalankannya (sebagai ganti menunggu permintaan sebelumnya selesai).</p>
461
462<p>Perhatikan bahwa metode {@link android.app.Service#onStartCommand onStartCommand()} harus mengembalikan
463integer. Integer tersebut merupakan nilai yang menjelaskan cara sistem melanjutkan layanan dalam
464kejadian yang dimatikan oleh sistem (sebagaimana dibahas di atas, implementasi default {@link
465android.app.IntentService} menangani hal ini untuk Anda, walaupun Anda bisa memodifikasinya). Nilai yang dikembalikan
466dari {@link android.app.Service#onStartCommand onStartCommand()} harus berupa salah satu
467konstanta berikut ini:</p>
468
469<dl>
470  <dt>{@link android.app.Service#START_NOT_STICKY}</dt>
471    <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand
472onStartCommand()} dikembalikan, <em>jangan</em> membuat lagi layanan tersebut, kecuali jika ada intent
473tertunda yang akan disampaikan. Inilah pilihan teraman untuk menghindari menjalankan layanan Anda
474bila tidak diperlukan dan bila aplikasi Anda bisa me-restart pekerjaan yang belum selesai.</dd>
475  <dt>{@link android.app.Service#START_STICKY}</dt>
476    <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand
477onStartCommand()} dikembalikan, buat kembali layanan dan panggil {@link
478android.app.Service#onStartCommand onStartCommand()}, namun <em>jangan</em> menyampaikan ulang intent terakhir.
479Sebagai gantinya, sistem akan memanggil {@link android.app.Service#onStartCommand onStartCommand()} dengan
480intent null, kecuali jika ada intent tertunda untuk memulai layanan, dan dalam hal ini,
481intent tersebut disampaikan. Ini cocok bagi pemutar media (atau layanan serupa) yang tidak
482mengeksekusi perintah, namun berjalan terus-menerus dan menunggu pekerjaan.</dd>
483  <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
484    <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand
485onStartCommand()} kembali, buat kembali layanan dan panggil {@link
486android.app.Service#onStartCommand onStartCommand()} dengan intent terakhir yang disampaikan ke
487layanan. Intent yang tertunda akan disampaikan pada gilirannya. Ini cocok bagi layanan yang
488aktif melakukan pekerjaan yang harus segera dilanjutkan, misalnya mengunduh file.</dd>
489</dl>
490<p>Untuk detail selengkapnya tentang nilai pengembalian ini, lihat dokumentasi acuan untuk setiap
491konstanta.</p>
492
493
494
495<h3 id="StartingAService">Memulai Layanan</h3>
496
497<p>Anda bisa memulai layanan dari aktivitas atau komponen aplikasi lain dengan meneruskan
498{@link android.content.Intent} (yang menetapkan layanan yang akan dimulai) ke {@link
499android.content.Context#startService startService()}. Sistem Android akan memanggil metode {@link
500android.app.Service#onStartCommand onStartCommand()} layanan dan meneruskan {@link
501android.content.Intent} padanya. (Jangan sekali-kali memanggil {@link android.app.Service#onStartCommand
502onStartCommand()} secara langsung.)</p>
503
504<p>Misalnya, aktivitas bisa memulai contoh layanan di bagian sebelumnya ({@code
505HelloSevice}) menggunakan intent eksplisit dengan {@link android.content.Context#startService
506startService()}:</p>
507
508<pre>
509Intent intent = new Intent(this, HelloService.class);
510startService(intent);
511</pre>
512
513<p>Metode {@link android.content.Context#startService startService()} segera kembali dan
514sistem Android akan memanggil metode {@link android.app.Service#onStartCommand
515onStartCommand()} layanan. Jika layanan belum berjalan, sistem mula-mula memanggil {@link
516android.app.Service#onCreate onCreate()}, kemudian memanggil {@link android.app.Service#onStartCommand
517onStartCommand()}.</p>
518
519<p>Jika layanan juga tidak menyediakan pengikatan, intent yang disampaikan dengan {@link
520android.content.Context#startService startService()} adalah satu-satunya mode komunikasi antara
521komponen aplikasi dan layanan. Akan tetapi, jika Anda ingin agar layanan mengirimkan hasilnya kembali, maka
522klien yang memulai layanan bisa membuat {@link android.app.PendingIntent} untuk siaran
523(dengan {@link android.app.PendingIntent#getBroadcast getBroadcast()}) dan menyampaikannya ke layanan
524dalam {@link android.content.Intent} yang memulai layanan. Layanan kemudian bisa menggunakan
525siaran untuk menyampaikan hasil.</p>
526
527<p>Beberapa permintaan untuk memulai layanan menghasilkan beberapa panggilan pula ke
528{@link android.app.Service#onStartCommand onStartCommand()} layanan. Akan tetapi, hanya satu permintaan untuk menghentikan
529layanan (dengan {@link android.app.Service#stopSelf stopSelf()} atau {@link
530android.content.Context#stopService stopService()}) dibutuhkan untuk menghentikannya.</p>
531
532
533<h3 id="Stopping">Menghentikan layanan</h3>
534
535<p>Layanan yang sudah dimulai harus mengelola daur hidupnya sendiri. Artinya, sistem tidak menghentikan atau
536memusnahkan layanan kecuali jika harus memulihkan memori sistem dan layanan
537terus berjalan setelah {@link android.app.Service#onStartCommand onStartCommand()} kembali. Jadi,
538layanan tersebut harus berhenti sendiri dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau
539komponen lain bisa menghentikannya dengan memanggil {@link android.content.Context#stopService stopService()}.</p>
540
541<p>Setelah diminta untuk berhenti dengan {@link android.app.Service#stopSelf stopSelf()} atau {@link
542android.content.Context#stopService stopService()}, sistem akan menghapus layanan
543secepatnya.</p>
544
545<p>Akan tetapi, bila layanan Anda menangani beberapa permintaan ke {@link
546android.app.Service#onStartCommand onStartCommand()} sekaligus, Anda tidak boleh menghentikan
547layanan bila Anda baru selesai memproses permintaan memulai, karena setelah itu mungkin Anda sudah menerima permintaan memulai
548yang baru (berhenti pada permintaan pertama akan menghentikan permintaan kedua). Untuk menghindari
549masalah ini, Anda bisa menggunakan {@link android.app.Service#stopSelf(int)} untuk memastikan bahwa permintaan
550Anda untuk menghentikan layanan selalu berdasarkan pada permintaan memulai terbaru. Artinya, bila Anda memanggil {@link
551android.app.Service#stopSelf(int)}, Anda akan meneruskan ID permintaan memulai (<code>startId</code>
552yang disampaikan ke {@link android.app.Service#onStartCommand onStartCommand()}) yang terkait dengan permintaan berhenti
553Anda. Kemudian jika layanan menerima permintaan memulai baru sebelum Anda bisa memanggil {@link
554android.app.Service#stopSelf(int)}, maka ID tidak akan sesuai dan layanan tidak akan berhenti.</p>
555
556<p class="caution"><strong>Perhatian:</strong> Aplikasi Anda perlu menghentikan layanannya
557bila selesai bekerja untuk menghindari pemborosan sumber daya sistem dan tenaga baterai. Jika perlu,
558komponen lain bisa menghentikan layanan secara eksplisit dengan memanggil {@link
559android.content.Context#stopService stopService()}. Bahkan jika Anda mengaktifkan pengikatan bagi layanan,
560Anda harus selalu menghentikan layanan sendiri jika layanan tersebut menerima panggilan ke {@link
561android.app.Service#onStartCommand onStartCommand()}.</p>
562
563<p>Untuk informasi selengkapnya tentang daur hidup layanan, lihat bagian di bawah ini tentang <a href="#Lifecycle">Mengelola Daur Hidup Layanan</a>.</p>
564
565
566
567<h2 id="CreatingBoundService">Membuat Layanan Terikat</h2>
568
569<p>Layanan terikat adalah layanan yang memungkinkan komponen aplikasi untuk mengikatnya dengan memanggil {@link
570android.content.Context#bindService bindService()} guna membuat koneksi yang berlangsung lama
571(dan umumnya tidak mengizinkan komponen untuk <em>memulainya</em> dengan memanggil {@link
572android.content.Context#startService startService()}).</p>
573
574<p>Anda sebaiknya membuat layanan terikat bila ingin berinteraksi dengan layanan dari aktivitas
575dan komponen lain dalam aplikasi Anda atau mengeskpos sebagian fungsionalitas aplikasi Anda ke
576ke aplikasi lain, melalui komunikasi antarproses (IPC).</p>
577
578<p>Untuk membuat layanan terikat, Anda harus mengimplementasikan metode callback {@link
579android.app.Service#onBind onBind()} untuk mengembalikan {@link android.os.IBinder} yang
580mendefinisikan antarmuka bagi komunikasi dengan layanan. Komponen aplikasi lain kemudian bisa memanggil
581{@link android.content.Context#bindService bindService()} untuk mengambil antarmuka dan
582mulai memanggil metode pada layanan. Layanan hanya hidup untuk melayani komponen aplikasi yang
583terikat padanya, jadi bila tidak ada komponen yang terikat pada layanan, sistem akan memusnahkannya
584(Anda <em>tidak</em> perlu menghentikan layanan terikat seperti halnya bila layanan dimulai
585melalui {@link android.app.Service#onStartCommand onStartCommand()}).</p>
586
587<p>Untuk membuat layanan terikat, hal yang perlu dilakukan pertama kali adalah mendefinisikan antarmuka yang menetapkan
588cara klien berkomunikasi dengan layanan. Antarmuka antara layanan
589dan klien ini harus berupa implementasi {@link android.os.IBinder} dan yang harus dikembalikan
590layanan Anda dari metode callback {@link android.app.Service#onBind
591onBind()}. Setelah menerima {@link android.os.IBinder}, klien bisa mulai
592berinteraksi dengan layanan melalui antarmuka tersebut.</p>
593
594<p>Beberapa klien bisa mengikat ke layanan sekaligus. Bila klien selesai berinteraksi dengan
595layanan, klien akan memanggil {@link android.content.Context#unbindService unbindService()} untuk melepas ikatan. Bila
596tidak ada klien yang terikat pada layanan, sistem akan menghapus layanan tersebut.</p>
597
598<p>Ada beberapa cara untuk mengimplementasikan layanan terikat dan implementasinya lebih
599rumit daripada layanan yang sudah dimulai, jadi layanan terikat dibahas dalam dokumen
600terpisah tentang <a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a>.</p>
601
602
603
604<h2 id="Notifications">Mengirim Pemberitahuan ke Pengguna</h2>
605
606<p>Setelah berjalan, layanan bisa memberi tahu pengguna tentang suatu kejadian menggunakan <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Pemberitahuan Toast</a> atau <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Pemberitahuan Baris Status</a>.</p>
607
608<p>Pemberitahuan Toast adalah pesan yang muncul sebentar pada permukaan jendela saat ini
609kemudian menghilang, sementara pemberitahuan baris status memberikan ikon di baris status dengan
610pesan yang bisa dipilih oleh pengguna untuk melakukan suatu tindakan (misalnya memulai suatu aktivitas).</p>
611
612<p>Biasanya, pemberitahuan baris status adalah teknik terbaik bila ada pekerjaan latar belakang yang sudah selesai
613(misalnya file selesai
614diunduh) dan pengguna kini bisa menggunakannya. Bila pengguna memilih pemberitahuan dari
615tampilan diperluas, pemberitahuan akan bisa memulai aktivitas (misalnya menampilkan file yang baru diunduh).</p>
616
617<p>Lihat panduan pengembang <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Pemberitahuan Toast</a> atau <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Pemberitahuan Baris Status</a>
618untuk informasi selengkapnya.</p>
619
620
621
622<h2 id="Foreground">Menjalankan Layanan di Latar Depan</h2>
623
624<p>Layanan latar depan adalah layanan yang dianggap sebagai sesuatu yang
625diketahui secara aktif oleh pengguna, jadi bukan sesuatu yang akan dihapus oleh sistem bila memori menipis. Sebuah
626layanan latar depan harus memberikan pemberitahuan bagi baris status, yang ditempatkan pada
627heading "Ongoing" yang artinya pemberitahuan tersebut tidak bisa diabaikan kecuali jika layanan
628dihentikan atau dihapus dari latar depan.</p>
629
630<p>Misalnya, pemutar musik yang memutar musik dari suatu layanan harus diatur untuk berjalan di
631latar depan, karena pengguna mengetahui operasi tersebut
632secara eksplisit. Pemberitahuan di baris status bisa menunjukkan lagu saat ini dan memungkinkan
633pengguna untuk menjalankan suatu aktivitas untuk berinteraksi dengan pemutar musik.</p>
634
635<p>Untuk meminta agar layanan Anda berjalan di latar depan, panggil {@link
636android.app.Service#startForeground startForeground()}. Metode ini memerlukan dua parameter: sebuah integer
637yang mengidentifikasi pemberitahuan secara unik dan {@link
638android.app.Notification} untuk baris status. Misalnya:</p>
639
640<pre>
641Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
642        System.currentTimeMillis());
643Intent notificationIntent = new Intent(this, ExampleActivity.class);
644PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
645notification.setLatestEventInfo(this, getText(R.string.notification_title),
646        getText(R.string.notification_message), pendingIntent);
647startForeground(ONGOING_NOTIFICATION_ID, notification);
648</pre>
649
650<p class="caution"><strong>Perhatian:</strong> ID integer yang Anda berikan ke {@link
651android.app.Service#startForeground startForeground()} tidak boleh 0.</p>
652
653
654<p>Untuk menghapus layanan dari latar depan, panggil {@link
655android.app.Service#stopForeground stopForeground()}. Metode ini memerlukan boolean, yang menunjukkan
656apakah pemberitahuan baris status juga akan dihapus. Metode ini <em>tidak</em> menghentikan
657layanan. Akan tetapi, jika Anda menghentikan layanan saat masih berjalan di latar depan
658maka pemberitahuan juga akan dihapus.</p>
659
660<p>Untuk informasi selengkapnya tentang pemberitahuan, lihat <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Membuat Pemberitahuan
661Baris Status</a>.</p>
662
663
664
665<h2 id="Lifecycle">Mengelola Daur Hidup Layanan</h2>
666
667<p>Daur hidup layanan jauh lebih sederhana daripada daur hidup aktivitas. Akan tetapi, lebih penting lagi adalah
668memerhatikan dengan cermat bagaimana layanan Anda dibuat dan dimusnahkan, karena suatu layanan
669bisa berjalan di latar belakang tanpa disadari oleh pengguna.</p>
670
671<p>Daur hidup layanan&mdash;dari saat dibuat hingga dimusnahkan&mdash;bisa mengikuti
672dua path berbeda:</p>
673
674<ul>
675<li>Layanan yang sudah dimulai
676  <p>Layanan dibuat bila komponen lain memanggil {@link
677android.content.Context#startService startService()}. Layanan kemudian berjalan terus-menerus dan harus
678berhenti sendiri dengan memanggil {@link
679android.app.Service#stopSelf() stopSelf()}. Komponen lain juga bisa menghentikan
680layanan dengan memanggil {@link android.content.Context#stopService
681stopService()}. Bila layanan dihentikan, sistem akan menghancurkannya.</p></li>
682
683<li>Layanan terikat
684  <p>Layanan dibuat bila komponen lain (klien) memanggil {@link
685android.content.Context#bindService bindService()}. Klien kemudian berkomunikasi dengan layanan
686melalui antarmuka {@link android.os.IBinder}. Klien bisa menutup koneksi dengan memanggil
687{@link android.content.Context#unbindService unbindService()}. Sejumlah klien bisa mengikat pada
688layanan yang sama dan bila semuanya melepas ikatan, sistem akan memusnahkan layanan tersebut. (Layanan
689<em>tidak</em> perlu berhenti sendiri.)</p></li>
690</ul>
691
692<p>Kedua path tersebut tidak benar-benar terpisah. Artinya, Anda bisa mengikat ke layanan yang sudah
693dimulai dengan {@link android.content.Context#startService startService()}. Misalnya, layanan
694musik latar belakang bisa dimulai dengan memanggil {@link android.content.Context#startService
695startService()} dengan {@link android.content.Intent} yang mengidentifikasi musik yang akan diputar. Kemudian,
696mungkin saat pengguna ingin mengontrol pemutar musik atau mendapatkan informasi
697tentang lagu yang diputar, aktivitas bisa mengikat ke layanan dengan memanggil {@link
698android.content.Context#bindService bindService()}. Dalam kasus seperti ini, {@link
699android.content.Context#stopService stopService()} atau {@link android.app.Service#stopSelf
700stopSelf()} tidak menghentikan layanan sampai semua klien melepas ikatan. </p>
701
702
703<h3 id="LifecycleCallbacks">Mengimplementasikan callback daur hidup</h3>
704
705<p>Seperti halnya aktivitas, layanan memiliki metode callback daur hidup yang bisa Anda implementasikan
706untuk memantau perubahan status layanan dan melakukan pekerjaan pada waktu yang tepat. Layanan skeleton
707berikut memperagakan setiap metode daur hidup:</p>
708
709<pre>
710public class ExampleService extends Service {
711    int mStartMode;       // indicates how to behave if the service is killed
712    IBinder mBinder;      // interface for clients that bind
713    boolean mAllowRebind; // indicates whether onRebind should be used
714
715    &#64;Override
716    public void {@link android.app.Service#onCreate onCreate}() {
717        // The service is being created
718    }
719    &#64;Override
720    public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
721        // The service is starting, due to a call to {@link android.content.Context#startService startService()}
722        return <em>mStartMode</em>;
723    }
724    &#64;Override
725    public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
726        // A client is binding to the service with {@link android.content.Context#bindService bindService()}
727        return <em>mBinder</em>;
728    }
729    &#64;Override
730    public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
731        // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
732        return <em>mAllowRebind</em>;
733    }
734    &#64;Override
735    public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
736        // A client is binding to the service with {@link android.content.Context#bindService bindService()},
737        // after onUnbind() has already been called
738    }
739    &#64;Override
740    public void {@link android.app.Service#onDestroy onDestroy}() {
741        // The service is no longer used and is being destroyed
742    }
743}
744</pre>
745
746<p class="note"><strong>Catatan:</strong> Tidak seperti metode callback daur hidup aktivitas, Anda
747<em>tidak</em> perlu memanggil implementasi superkelas metode callback tersebut.</p>
748
749<img src="{@docRoot}images/service_lifecycle.png" alt="" />
750<p class="img-caption"><strong>Gambar 2.</strong> Daur hidup layanan. Diagram di sebelah kiri
751menampilkan daur hidup bila layanan dibuat dengan {@link android.content.Context#startService
752startService()} dan diagram di sebelah kanan menampilkan daur hidup bila layanan dibuat
753dengan {@link android.content.Context#bindService bindService()}.</p>
754
755<p>Dengan mengimplementasikan metode-metode ini, Anda bisa memantau dua loop tersarang (nested loop) daur hidup layanan: </p>
756
757<ul>
758<li><strong>Seluruh masa pakai</strong> layanan terjadi antara saat {@link
759android.app.Service#onCreate onCreate()} dipanggil dan saat {@link
760android.app.Service#onDestroy} kembali. Seperti halnya aktivitas, layanan melakukan penyiapan awal di
761{@link android.app.Service#onCreate onCreate()} dan melepaskan semua sisa sumber daya yang ada di {@link
762android.app.Service#onDestroy onDestroy()}.  Misalnya,
763layanan pemutar musik bisa membuat thread tempat musik akan diputar dalam {@link
764android.app.Service#onCreate onCreate()}, kemudian menghentikan thread tersebut dalam {@link
765android.app.Service#onDestroy onDestroy()}.
766
767<p>Metode {@link android.app.Service#onCreate onCreate()} dan {@link android.app.Service#onDestroy
768onDestroy()} diperlukan semua layanan, baik yang
769dibuat oleh {@link android.content.Context#startService startService()} maupun {@link
770android.content.Context#bindService bindService()}.</p></li>
771
772<li><strong>Masa pakai aktif</strong> layanan dimulai dengan panggilan ke {@link
773android.app.Service#onStartCommand onStartCommand()} atau {@link android.app.Service#onBind onBind()}.
774Masing-masing metode diberikan {@link
775android.content.Intent} yang diteruskan ke {@link android.content.Context#startService
776startService()} atau {@link android.content.Context#bindService bindService()}.
777<p>Jika layanan telah dimulai, masa pakai aktif akan berakhir pada saat yang sama dengan
778berakhirnya seluruh masa pakai (layanan masih aktif bahkan setelah {@link android.app.Service#onStartCommand
779onStartCommand()} kembali). Jika layanan tersebut terikat, masa pakai aktifnya akan berakhir bila {@link
780android.app.Service#onUnbind onUnbind()} kembali.</p>
781</li>
782</ul>
783
784<p class="note"><strong>Catatan:</strong> Meskipun layanan yang sudah dimulai dihentikan dengan panggilan ke
785{@link android.app.Service#stopSelf stopSelf()} atau {@link
786android.content.Context#stopService stopService()}, tidak ada callback tersendiri bagi
787layanan tersebut (tidak ada callback {@code onStop()}). Jadi, kecuali jika layanan terikat ke klien,
788sistem akan memusnahkannya bila layanan dihentikan&mdash;{@link
789android.app.Service#onDestroy onDestroy()} adalah satu-satunya callback yang diterima.</p>
790
791<p>Gambar 2 mengilustrasikan metode callback yang lazim bagi suatu layanan. Walaupun gambar tersebut memisahkan
792layanan yang dibuat oleh {@link android.content.Context#startService startService()} dari layanan
793yang dibuat oleh {@link android.content.Context#bindService bindService()}, ingatlah
794bahwa suatu layanan, bagaimana pun dimulainya, bisa memungkinkan klien mengikat padanya.
795Jadi, suatu layanan yang awalnya dimulai dengan {@link android.app.Service#onStartCommand
796onStartCommand()} (oleh klien yang memanggil {@link android.content.Context#startService startService()})
797masih bisa menerima panggilan ke {@link android.app.Service#onBind onBind()} (bila klien memanggil
798{@link android.content.Context#bindService bindService()}).</p>
799
800<p>Untuk informasi selengkapnya tentang membuat layanan yang menyediakan pengikatan, lihat dokumen <a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a>,
801yang menyertakan informasi selengkapnya tentang metode callback {@link android.app.Service#onRebind onRebind()}
802di bagian tentang <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">Mengelola Daur Hidup
803Layanan Terikat</a>.</p>
804
805
806<!--
807<h2>Beginner's Path</h2>
808
809<p>To learn how to query data from the system or other applications (such as contacts or media
810stored on the device), continue with the <b><a
811href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b>
812document.</p>
813-->
814