| page.title=Layanan |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <ol id="qv"> |
| <h2>Dalam dokumen ini</h2> |
| <ol> |
| <li><a href="#Basics">Dasar-Dasar</a></li> |
| <ol> |
| <li><a href="#Declaring">Mendeklarasikan layanan dalam manifes</a></li> |
| </ol> |
| <li><a href="#CreatingAService">Membuat Layanan yang Sudah Dimulai</a> |
| <ol> |
| <li><a href="#ExtendingIntentService">Memperluas kelas IntentService</a></li> |
| <li><a href="#ExtendingService">Memperluas kelas Layanan</a></li> |
| <li><a href="#StartingAService">Memulai layanan</a></li> |
| <li><a href="#Stopping">Menghentikan layanan</a></li> |
| </ol> |
| </li> |
| <li><a href="#CreatingBoundService">Membuat Layanan Terikat</a></li> |
| <li><a href="#Notifications">Mengirim Pemberitahuan ke Pengguna</a></li> |
| <li><a href="#Foreground">Menjalankan Layanan di Latar Depan</a></li> |
| <li><a href="#Lifecycle">Mengelola Daur Hidup Layanan</a> |
| <ol> |
| <li><a href="#LifecycleCallbacks">Mengimplementasikan callback daur hidup</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Kelas-kelas utama</h2> |
| <ol> |
| <li>{@link android.app.Service}</li> |
| <li>{@link android.app.IntentService}</li> |
| </ol> |
| |
| <h2>Contoh</h2> |
| <ol> |
| <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code |
| ServiceStartArguments}</a></li> |
| <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code |
| LocalService}</a></li> |
| </ol> |
| |
| <h2>Lihat juga</h2> |
| <ol> |
| <li><a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a></li> |
| </ol> |
| |
| </div> |
| |
| |
| <p>{@link android.app.Service} adalah sebuah komponen aplikasi yang bisa melakukan |
| operasi yang berjalan lama di latar belakang dan tidak menyediakan antarmuka pengguna. Komponen |
| aplikasi lain bisa memulai layanan dan komponen aplikasi tersebut akan terus berjalan |
| di latar belakang walaupun pengguna beralih ke aplikasi lain. Selain itu, komponen bisa mengikat ke layanan |
| untuk berinteraksi dengannya dan bahkan melakukan komunikasi antarproses (IPC). Misalnya, layanan mungkin |
| menangani transaksi jaringan, memutar musik, melakukan file I/O, atau berinteraksi dengan penyedia konten |
| dari latar belakang.</p> |
| |
| <p>Ada dua bentuk dasar layanan:</p> |
| |
| <dl> |
| <dt>Sudah Dimulai</dt> |
| <dd>Layanan "sudah dimulai" bila komponen aplikasi (misalnya aktivitas) memulainya dengan |
| memanggil {@link android.content.Context#startService startService()}. Sesudah dimulai, layanan |
| bisa berjalan terus-menerus di latar belakang walaupun komponen yang memulainya telah dimusnahkan. Biasanya, |
| layanan yang sudah dimulai akan melakukan operasi tunggal dan tidak mengembalikan hasil ke pemanggilnya. |
| Misalnya, layanan bisa mengunduh atau mengunggah file melalui jaringan. Bila operasi selesai, |
| layanan seharusnya berhenti sendiri.</dd> |
| <dt>Terikat</dt> |
| <dd>Layanan "terikat" bila komponen aplikasi mengikat kepadanya dengan memanggil {@link |
| android.content.Context#bindService bindService()}. Layanan terikat menawarkan antarmuka |
| klien-server yang memungkinkan komponen berinteraksi dengan layanan tersebut, mengirim permintaan, mendapatkan hasil dan bahkan |
| melakukannya pada sejumlah proses dengan komunikasi antarproses (IPC). Layanan terikat hanya berjalan selama |
| ada komponen aplikasi lain yang terikat padanya. Sejumlah komponen bisa terikat pada layanan secara bersamaan, |
| namun bila semuanya melepas ikatan, layanan tersebut akan dimusnahkan.</dd> |
| </dl> |
| |
| <p>Walaupun dokumentasi ini secara umum membahas kedua jenis layanan secara terpisah, layanan |
| Anda bisa menggunakan keduanya—layanan bisa dimulai (untuk berjalan terus-menerus) sekaligus memungkinkan pengikatan. |
| Cukup mengimplementasikan dua metode callback: {@link |
| android.app.Service#onStartCommand onStartCommand()} untuk memungkinkan komponen memulainya dan {@link |
| android.app.Service#onBind onBind()} untuk memungkinkan pengikatan.</p> |
| |
| <p>Apakah aplikasi Anda sudah dimulai, terikat, atau keduanya, semua komponen aplikasi |
| bisa menggunakan layanan (bahkan dari aplikasi terpisah), demikian pula semua komponen bisa menggunakan |
| suatu aktivitas—dengan memulainya dengan {@link android.content.Intent}. Akan tetapi, Anda bisa mendeklarasikan |
| layanan sebagai privat, pada file manifes, dan memblokir akses dari aplikasi lain. Hal ini |
| dibahas selengkapnya di bagian tentang <a href="#Declaring">Mendeklarasikan layanan dalam |
| manifes</a>.</p> |
| |
| <p class="caution"><strong>Perhatian:</strong> Layanan berjalan di |
| thread utama proses yang menjadi host-nya—layanan <strong>tidak</strong> membuat thread-nya sendiri |
| dan <strong>tidak</strong> berjalan pada proses terpisah (kecuali bila Anda tentukan demikian). Artinya, |
| jika layanan Anda akan melakukan pekerjaan yang membutuhkan tenaga CPU besar atau operasi yang memblokir (seperti |
| pemutaran MP3 atau jaringan), Anda perlu membuat thread baru dalam layanan untuk melakukan pekerjaan tersebut. Dengan menggunakan |
| thread terpisah, Anda mengurangi risiko terjadinya kesalahan Aplikasi Tidak Merespons (Application Not Responding/ANR) dan |
| thread utama aplikasi bisa tetap dikhususkan pada interaksi pengguna dengan aktivitas Anda.</p> |
| |
| |
| <h2 id="Basics">Dasar-Dasar</h2> |
| |
| <div class="sidebox-wrapper"> |
| <div class="sidebox"> |
| <h3>Haruskah menggunakan layanan atau thread?</h3> |
| <p>Layanan sekadar komponen yang bisa berjalan di latar belakang walaupun pengguna sedang tidak |
| berinteraksi dengan aplikasi Anda. Sehingga, Anda harus membuat layanan bila memang itu |
| yang dibutuhkan.</p> |
| <p>Bila Anda perlu melakukan pekerjaan di luar thread utama, namun hanya bila pengguna sedang berinteraksi |
| dengan aplikasi, maka Anda harus membuat thread baru sebagai ganti layanan baru. Misalnya, |
| bila Anda ingin memutar musik, namun hanya saat aktivitas Anda berjalan, Anda bisa membuat |
| thread dalam {@link android.app.Activity#onCreate onCreate()}, mulai menjalankannya di {@link |
| android.app.Activity#onStart onStart()}, kemudian menghentikannya di {@link android.app.Activity#onStop |
| onStop()}. Pertimbangkan juga untuk menggunakan {@link android.os.AsyncTask} atau {@link android.os.HandlerThread}, |
| sebagai ganti kelas {@link java.lang.Thread} yang lazim digunakan. Lihat dokumen <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">Proses dan |
| Threading</a> untuk informasi selengkapnya tentang thread.</p> |
| <p>Ingatlah jika menggunakan layanan, layanan tersebut tetap berjalan di thread utama aplikasi Anda secara |
| default, jadi Anda harus tetap membuat thread baru dalam layanan bila layanan tersebut melakukan operasi yang intensif |
| atau operasi yang memblokir.</p> |
| </div> |
| </div> |
| |
| <p>Untuk membuat layanan, Anda harus membuat subkelas {@link android.app.Service} (atau |
| salah satu dari subkelasnya yang ada). Dalam implementasi, Anda perlu mengesampingkan sebagian metode callback yang |
| menangani aspek utama daur hidup layanan dan memberikan mekanisme bagi komponen untuk mengikat |
| pada layanan, bila dibutuhkan. Metode callback terpenting yang perlu Anda kesampingkan adalah:</p> |
| |
| <dl> |
| <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt> |
| <dd>Sistem akan memanggil metode ini bila komponen lain, misalnya aktivitas, |
| meminta dimulainya layanan, dengan memanggil {@link android.content.Context#startService |
| startService()}. Setelah metode ini dieksekusi, layanan akan dimulai dan bisa berjalan di |
| latar belakang terus-menerus. Jika mengimplementasikan ini, Anda bertanggung jawab menghentikan layanan bila |
| bila pekerjaannya selesai, dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau {@link |
| android.content.Context#stopService stopService()}. (Jika hanya ingin menyediakan pengikatan, Anda tidak |
| perlu mengimplementasikan metode ini.)</dd> |
| <dt>{@link android.app.Service#onBind onBind()}</dt> |
| <dd>Sistem akan memanggil metode ini bila komponen lain ingin mengikat pada |
| layanan (misalnya untuk melakukan RPC), dengan memanggil {@link android.content.Context#bindService |
| bindService()}. Dalam mengimplementasikan metode ini, Anda harus menyediakan antarmuka yang digunakan |
| klien untuk berkomunikasi dengan layanan, dengan mengembalikan {@link android.os.IBinder}. Anda harus selalu |
| mengimplementasikan metode ini, namun jika tidak ingin mengizinkan pengikatan, Anda perlu mengembalikan null.</dd> |
| <dt>{@link android.app.Service#onCreate()}</dt> |
| <dd>Sistem memanggil metode ini bila layanan dibuat untuk pertama kalinya, untuk melakukan prosedur |
| penyiapan satu kali (sebelum memanggil {@link android.app.Service#onStartCommand onStartCommand()} atau |
| {@link android.app.Service#onBind onBind()}). Bila layanan sudah berjalan, metode ini tidak |
| dipanggil.</dd> |
| <dt>{@link android.app.Service#onDestroy()}</dt> |
| <dd>Sistem memanggil metode ini bila layanan tidak lagi digunakan dan sedang dimusnahkan. |
| Layanan Anda perlu mengimplementasikannya untuk membersihkan sumber daya seperti thread, listener |
| terdaftar, penerima, dll. Ini adalah panggilan terakhir yang diterima layanan.</dd> |
| </dl> |
| |
| <p>Bila komponen memulai layanan dengan memanggil {@link |
| android.content.Context#startService startService()} (yang menyebabkan panggilan ke {@link |
| android.app.Service#onStartCommand onStartCommand()}), maka layanan |
| terus berjalan hingga terhenti sendiri dengan {@link android.app.Service#stopSelf()} atau bila komponen |
| lain menghentikannya dengan memanggil {@link android.content.Context#stopService stopService()}.</p> |
| |
| <p>Bila komponen memanggil |
| {@link android.content.Context#bindService bindService()} untuk membuat layanan (dan {@link |
| android.app.Service#onStartCommand onStartCommand()} <em>tidak</em> dipanggil), maka layanan hanya berjalan |
| selama komponen terikat kepadanya. Setelah layanan dilepas ikatannya dari semua klien, |
| sistem akan menghancurkannya.</p> |
| |
| <p>Sistem Android akan menghentikan paksa layanan hanya bila memori tinggal sedikit dan sistem harus memulihkan |
| sumber daya sistem untuk aktivitas yang mendapatkan fokus pengguna. Jika layanan terikat pada suatu aktivitas yang mendapatkan |
| fokus 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. |
| Sebaliknya, bila layanan sudah dimulai dan berjalan lama, maka sistem akan menurunkan posisinya |
| dalam daftar tugas latar belakang seiring waktu dan layanan akan sangat rentan untuk |
| dimatikan—bila layanan Anda dimulai, maka Anda harus mendesainnya agar bisa menangani restart |
| oleh sistem dengan baik. Jika sistem mematikan layanan Anda, layanan akan dimulai kembali begitu sumber daya |
| kembali tersedia (tetapi ini juga bergantung pada nilai yang Anda kembalikan dari {@link |
| android.app.Service#onStartCommand onStartCommand()}, sebagaimana akan dibahas nanti). Untuk informasi selengkapnya |
| tentang kapan sistem mungkin akan memusnahkan layanan, lihat dokumen |
| <a href="{@docRoot}guide/components/processes-and-threads.html">Proses dan Threading</a>.</p> |
| |
| <p>Dalam bagian selanjutnya, Anda akan melihat bagaimana membuat masing-masing tipe layanan dan cara menggunakannya |
| dari komponen aplikasi lain.</p> |
| |
| |
| |
| <h3 id="Declaring">Mendeklarasikan layanan dalam manifes</h3> |
| |
| <p>Sebagaimana aktivitas (dan komponen lainnya), Anda harus mendeklarasikan semua layanan dalam file manifes |
| aplikasi Anda.</p> |
| |
| <p>Untuk mendeklarasikan layanan Anda, tambahkan sebuah elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> |
| sebagai anak |
| elemen <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>. Misalnya:</p> |
| |
| <pre> |
| <manifest ... > |
| ... |
| <application ... > |
| <service android:name=".ExampleService" /> |
| ... |
| </application> |
| </manifest> |
| </pre> |
| |
| <p>Lihat acuan elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> |
| untuk informasi selengkapnya tentang cara mendeklarasikan layanan Anda dalam manifes.</p> |
| |
| <p>Ada atribut lain yang bisa Anda sertakan dalam elemen <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> untuk |
| mendefinisikan properti seperti izin yang dibutuhkan untuk memulai layanan dan proses |
| tempat berjalannya layanan. <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a> adalah satu-satunya atribut yang diperlukan |
| —atribut tersebut menetapkan nama kelas layanan. Setelah |
| mempublikasikan aplikasi, Anda tidak boleh mengubah nama ini, karena jika melakukannya, Anda bisa merusak |
| kode 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 |
| That Cannot Change</a>). |
| |
| <p>Untuk memastikan aplikasi Anda aman, <strong>selalu gunakan intent eksplisit saat memulai atau mengikat |
| {@link android.app.Service} Anda</strong> dan jangan mendeklarasikan filter intent untuk layanan. Jika |
| Anda perlu membiarkan adanya ambiguitas tentang layanan mana yang dimulai, Anda bisa |
| menyediakan filter intent bagi layanan dan tidak memasukkan nama komponen pada {@link |
| android.content.Intent}, namun Anda juga harus menyesuaikan paket bagi intent tersebut dengan {@link |
| android.content.Intent#setPackage setPackage()}, yang memberikan klarifikasi memadai bagi |
| target layanan.</p> |
| |
| <p>Anda juga bisa memastikan layanan tersedia hanya bagi aplikasi Anda dengan |
| menyertakan atribut <a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a> |
| dan mengaturnya ke {@code "false"}. Hal ini efektif menghentikan aplikasi lain agar tidak memulai |
| layanan Anda, bahkan saat menggunakan intent eksplisit.</p> |
| |
| |
| |
| |
| <h2 id="CreatingStartedService">Membuat Layanan yang Sudah Dimulai</h2> |
| |
| <p>Layanan yang sudah dimulai adalah layanan yang dimulai komponen lain dengan memanggil {@link |
| android.content.Context#startService startService()}, yang menyebabkan panggilan ke metode |
| {@link android.app.Service#onStartCommand onStartCommand()} layanan.</p> |
| |
| <p>Bila layanan sudah dimulai, layanan tersebut memiliki daur hidup yang tidak bergantung pada |
| komponen yang memulainya dan bisa berjalan terus-menerus di latar belakang walaupun |
| komponen yang memulainya dimusnahkan. Dengan sendirinya, layanan akan berhenti sendiri bila pekerjaannya |
| selesai dengan memanggil {@link android.app.Service#stopSelf stopSelf()}, atau komponen lain bisa menghentikannya |
| dengan memanggil {@link android.content.Context#stopService stopService()}.</p> |
| |
| <p>Komponen aplikasi seperti aktivitas bisa memulai layanan dengan memanggil {@link |
| android.content.Context#startService startService()} dan meneruskan {@link android.content.Intent} |
| yang menetapkan layanan dan menyertakan data untuk digunakan layanan. Layanan menerima |
| {@link android.content.Intent} ini dalam metode {@link android.app.Service#onStartCommand |
| onStartCommand()}.</p> |
| |
| <p>Sebagai contoh, anggaplah aktivitas perlu menyimpan data ke database online. Aktivitas tersebut bisa |
| memulai layanan pendamping dan mengiriminya data untuk disimpan dengan meneruskan intent ke {@link |
| android.content.Context#startService startService()}. Layanan akan menerima intent dalam {@link |
| android.app.Service#onStartCommand onStartCommand()}, menghubungkan ke Internet dan melakukan |
| transaksi database. Bila transaksi selesai, layanan akan berhenti sendiri dan |
| dimusnahkan.</p> |
| |
| <p class="caution"><strong>Perhatian:</strong> Layanan berjalan dalam proses yang sama dengan aplikasi |
| tempatnya dideklarasikan dan dalam thread utama aplikasi tersebut, secara default. Jadi, bila layanan Anda |
| melakukan operasi yang intensif atau operasi pemblokiran saat pengguna berinteraksi dengan aktivitas dari |
| aplikasi yang sama, layanan akan memperlambat kinerja aktivitas. Agar tidak memengaruhi |
| kinerja aplikasi, Anda harus memulai thread baru di dalam layanan.</p> |
| |
| <p>Biasanya, ada dua kelas yang bisa Anda perluas untuk membuat layanan yang sudah dimulai:</p> |
| <dl> |
| <dt>{@link android.app.Service}</dt> |
| <dd>Ini adalah kelas dasar untuk semua layanan. Bila memperluas kelas ini, Anda perlu |
| membuat thread baru sebagai tempat melaksanakan semua pekerjaan layanan tersebut, karena layanan |
| menggunakan thread utama aplikasi Anda secara default, dan hal ini bisa memperlambat |
| kinerja aktivitas yang dijalankan aplikasi Anda.</dd> |
| <dt>{@link android.app.IntentService}</dt> |
| <dd>Ini adalah subkelas {@link android.app.Service} yang menggunakan thread pekerja untuk menangani |
| semua permintaan memulai, satu per satu. Ini adalah pilihan terbaik jika Anda tidak mengharuskan layanan |
| menangani beberapa permintaan sekaligus. Anda cukup mengimplementasikan {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()}, yang menerima intent untuk setiap |
| permintaan memulai agar bisa melakukan pekerjaan latar belakang.</dd> |
| </dl> |
| |
| <p>Bagian selanjutnya membahas cara mengimplementasikan layanan Anda menggunakan |
| salah satu dari kelas-kelas ini.</p> |
| |
| |
| <h3 id="ExtendingIntentService">Memperluas kelas IntentService</h3> |
| |
| <p>Mengingat kebanyakan layanan yang sudah dimulai tidak perlu menangani beberapa permintaan |
| sekaligus (yang bisa berupa skenario multi-threading berbahaya), mungkin Anda sebaiknya mengimplementasikan |
| layanan menggunakan kelas {@link android.app.IntentService}.</p> |
| |
| <p>Berikut ini yang dilakukan {@link android.app.IntentService}:</p> |
| |
| <ul> |
| <li>Membuat thread pekerja default yang menjalankan semua intent yang disampaikan ke {@link |
| android.app.Service#onStartCommand onStartCommand()} terpisah dari thread utama aplikasi |
| Anda.</li> |
| <li>Membuat antrean pekerjaan yang meneruskan intent satu per satu ke implementasi {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()}, sehingga Anda tidak perlu |
| mengkhawatirkan multi-threading.</li> |
| <li>Menghentikan layanan setelah semua permintaan memulai telah ditangani, jadi Anda tidak perlu memanggil |
| {@link android.app.Service#stopSelf}.</li> |
| <li>Menyediakan implementasi default {@link android.app.IntentService#onBind onBind()} yang |
| mengembalikan null.</li> |
| <li>Menyediakan implementasi default {@link android.app.IntentService#onStartCommand |
| onStartCommand()} yang mengirimkan intent ke antrean pekerjaan kemudian ke implementasi {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()} Anda.</li> |
| </ul> |
| |
| <p>Oleh karena itu, Anda hanya perlu mengimplementasikan {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()} untuk melakukan pekerjaan yang diberikan oleh |
| klien. (Akan tetapi, Anda juga perlu menyediakan konstruktor kecil bagi layanan.)</p> |
| |
| <p>Berikut ini contoh implementasi {@link android.app.IntentService}:</p> |
| |
| <pre> |
| public class HelloIntentService extends IntentService { |
| |
| /** |
| * A constructor is required, and must call the super {@link android.app.IntentService#IntentService} |
| * constructor with a name for the worker thread. |
| */ |
| public HelloIntentService() { |
| super("HelloIntentService"); |
| } |
| |
| /** |
| * The IntentService calls this method from the default worker thread with |
| * the intent that started the service. When this method returns, IntentService |
| * stops the service, as appropriate. |
| */ |
| @Override |
| protected void onHandleIntent(Intent intent) { |
| // Normally we would do some work here, like download a file. |
| // For our sample, we just sleep for 5 seconds. |
| long endTime = System.currentTimeMillis() + 5*1000; |
| while (System.currentTimeMillis() < endTime) { |
| synchronized (this) { |
| try { |
| wait(endTime - System.currentTimeMillis()); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |
| } |
| </pre> |
| |
| <p>Anda hanya memerlukan: konstruktor dan implementasi {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()}.</p> |
| |
| <p>Jika Anda memutuskan untuk juga mengesampingkan metode callback lain, seperti {@link |
| android.app.IntentService#onCreate onCreate()}, {@link |
| android.app.IntentService#onStartCommand onStartCommand()}, atau {@link |
| android.app.IntentService#onDestroy onDestroy()}, pastikan memanggil implementasi super, sehingga |
| {@link android.app.IntentService} bisa menangani hidup thread pekerja dengan baik.</p> |
| |
| <p>Misalnya, {@link android.app.IntentService#onStartCommand onStartCommand()} harus mengembalikan |
| implementasi default (yang merupakan cara penyampaian intent ke {@link |
| android.app.IntentService#onHandleIntent onHandleIntent()}):</p> |
| |
| <pre> |
| @Override |
| public int onStartCommand(Intent intent, int flags, int startId) { |
| Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); |
| return super.onStartCommand(intent,flags,startId); |
| } |
| </pre> |
| |
| <p>Selain {@link android.app.IntentService#onHandleIntent onHandleIntent()}, satu-satunya metode lain |
| yang tidak mengharuskan Anda memanggil super kelas adalah {@link android.app.IntentService#onBind |
| onBind()} (namun Anda hanya perlu mengimplementasikannya bila layanan mengizinkan pengikatan).</p> |
| |
| <p>Dalam bagian berikutnya, Anda akan melihat bagaimana layanan serupa diimplementasikan saat |
| memperluas kelas {@link android.app.Service} basis, yang membutuhkan kode lebih banyak lagi, namun mungkin |
| cocok jika Anda perlu menangani beberapa permintaan memulai sekaligus.</p> |
| |
| |
| <h3 id="ExtendingService">Memperluas kelas Layanan</h3> |
| |
| <p>Seperti telah Anda lihat di bagian sebelumnya, menggunakan {@link android.app.IntentService} membuat |
| implementasi layanan yang sudah dimulai jadi sangat sederhana. Namun, bila Anda mengharuskan layanan untuk |
| melakukan multi-threading (sebagai ganti memproses permintaan memulai melalui antrean pekerjaan), maka Anda |
| bisa memperluas kelas {@link android.app.Service} untuk menangani masing-masing intent.</p> |
| |
| <p>Sebagai perbandingan, contoh kode berikut ini adalah implementasi kelas {@link |
| android.app.Service} yang melakukan pekerjaan yang persis sama dengan contoh di atas menggunakan {@link |
| android.app.IntentService}. Artinya, untuk setiap permintaan memulai, kode tersebut akan menggunakan thread pekerja |
| untuk melakukan pekerjaan dan memproses permintaan satu per satu.</p> |
| |
| <pre> |
| public class HelloService extends Service { |
| private Looper mServiceLooper; |
| private ServiceHandler mServiceHandler; |
| |
| // Handler that receives messages from the thread |
| private final class ServiceHandler extends Handler { |
| public ServiceHandler(Looper looper) { |
| super(looper); |
| } |
| @Override |
| public void handleMessage(Message msg) { |
| // Normally we would do some work here, like download a file. |
| // For our sample, we just sleep for 5 seconds. |
| long endTime = System.currentTimeMillis() + 5*1000; |
| while (System.currentTimeMillis() < endTime) { |
| synchronized (this) { |
| try { |
| wait(endTime - System.currentTimeMillis()); |
| } catch (Exception e) { |
| } |
| } |
| } |
| // Stop the service using the startId, so that we don't stop |
| // the service in the middle of handling another job |
| stopSelf(msg.arg1); |
| } |
| } |
| |
| @Override |
| public void onCreate() { |
| // Start up the thread running the service. Note that we create a |
| // separate thread because the service normally runs in the process's |
| // main thread, which we don't want to block. We also make it |
| // background priority so CPU-intensive work will not disrupt our UI. |
| HandlerThread thread = new HandlerThread("ServiceStartArguments", |
| Process.THREAD_PRIORITY_BACKGROUND); |
| thread.start(); |
| |
| // Get the HandlerThread's Looper and use it for our Handler |
| mServiceLooper = thread.getLooper(); |
| mServiceHandler = new ServiceHandler(mServiceLooper); |
| } |
| |
| @Override |
| public int onStartCommand(Intent intent, int flags, int startId) { |
| Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); |
| |
| // For each start request, send a message to start a job and deliver the |
| // start ID so we know which request we're stopping when we finish the job |
| Message msg = mServiceHandler.obtainMessage(); |
| msg.arg1 = startId; |
| mServiceHandler.sendMessage(msg); |
| |
| // If we get killed, after returning from here, restart |
| return START_STICKY; |
| } |
| |
| @Override |
| public IBinder onBind(Intent intent) { |
| // We don't provide binding, so return null |
| return null; |
| } |
| |
| @Override |
| public void onDestroy() { |
| Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); |
| } |
| } |
| </pre> |
| |
| <p>Seperti yang bisa Anda lihat, ini membutuhkan lebih banyak pekerjaan daripada menggunakan {@link android.app.IntentService}.</p> |
| |
| <p>Akan tetapi, karena Anda menangani sendiri setiap panggilan ke {@link android.app.Service#onStartCommand |
| onStartCommand()}, Anda bisa melakukan beberapa permintaan sekaligus. Itu bukan yang |
| dilakukan contoh ini, namun jika itu yang diinginkan, Anda bisa membuat thread baru untuk setiap |
| permintaan dan langsung menjalankannya (sebagai ganti menunggu permintaan sebelumnya selesai).</p> |
| |
| <p>Perhatikan bahwa metode {@link android.app.Service#onStartCommand onStartCommand()} harus mengembalikan |
| integer. Integer tersebut merupakan nilai yang menjelaskan cara sistem melanjutkan layanan dalam |
| kejadian yang dimatikan oleh sistem (sebagaimana dibahas di atas, implementasi default {@link |
| android.app.IntentService} menangani hal ini untuk Anda, walaupun Anda bisa memodifikasinya). Nilai yang dikembalikan |
| dari {@link android.app.Service#onStartCommand onStartCommand()} harus berupa salah satu |
| konstanta berikut ini:</p> |
| |
| <dl> |
| <dt>{@link android.app.Service#START_NOT_STICKY}</dt> |
| <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand |
| onStartCommand()} dikembalikan, <em>jangan</em> membuat lagi layanan tersebut, kecuali jika ada intent |
| tertunda yang akan disampaikan. Inilah pilihan teraman untuk menghindari menjalankan layanan Anda |
| bila tidak diperlukan dan bila aplikasi Anda bisa me-restart pekerjaan yang belum selesai.</dd> |
| <dt>{@link android.app.Service#START_STICKY}</dt> |
| <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand |
| onStartCommand()} dikembalikan, buat kembali layanan dan panggil {@link |
| android.app.Service#onStartCommand onStartCommand()}, namun <em>jangan</em> menyampaikan ulang intent terakhir. |
| Sebagai gantinya, sistem akan memanggil {@link android.app.Service#onStartCommand onStartCommand()} dengan |
| intent null, kecuali jika ada intent tertunda untuk memulai layanan, dan dalam hal ini, |
| intent tersebut disampaikan. Ini cocok bagi pemutar media (atau layanan serupa) yang tidak |
| mengeksekusi perintah, namun berjalan terus-menerus dan menunggu pekerjaan.</dd> |
| <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt> |
| <dd>Jika sistem mematikan layanan setelah {@link android.app.Service#onStartCommand |
| onStartCommand()} kembali, buat kembali layanan dan panggil {@link |
| android.app.Service#onStartCommand onStartCommand()} dengan intent terakhir yang disampaikan ke |
| layanan. Intent yang tertunda akan disampaikan pada gilirannya. Ini cocok bagi layanan yang |
| aktif melakukan pekerjaan yang harus segera dilanjutkan, misalnya mengunduh file.</dd> |
| </dl> |
| <p>Untuk detail selengkapnya tentang nilai pengembalian ini, lihat dokumentasi acuan untuk setiap |
| konstanta.</p> |
| |
| |
| |
| <h3 id="StartingAService">Memulai Layanan</h3> |
| |
| <p>Anda bisa memulai layanan dari aktivitas atau komponen aplikasi lain dengan meneruskan |
| {@link android.content.Intent} (yang menetapkan layanan yang akan dimulai) ke {@link |
| android.content.Context#startService startService()}. Sistem Android akan memanggil metode {@link |
| android.app.Service#onStartCommand onStartCommand()} layanan dan meneruskan {@link |
| android.content.Intent} padanya. (Jangan sekali-kali memanggil {@link android.app.Service#onStartCommand |
| onStartCommand()} secara langsung.)</p> |
| |
| <p>Misalnya, aktivitas bisa memulai contoh layanan di bagian sebelumnya ({@code |
| HelloSevice}) menggunakan intent eksplisit dengan {@link android.content.Context#startService |
| startService()}:</p> |
| |
| <pre> |
| Intent intent = new Intent(this, HelloService.class); |
| startService(intent); |
| </pre> |
| |
| <p>Metode {@link android.content.Context#startService startService()} segera kembali dan |
| sistem Android akan memanggil metode {@link android.app.Service#onStartCommand |
| onStartCommand()} layanan. Jika layanan belum berjalan, sistem mula-mula memanggil {@link |
| android.app.Service#onCreate onCreate()}, kemudian memanggil {@link android.app.Service#onStartCommand |
| onStartCommand()}.</p> |
| |
| <p>Jika layanan juga tidak menyediakan pengikatan, intent yang disampaikan dengan {@link |
| android.content.Context#startService startService()} adalah satu-satunya mode komunikasi antara |
| komponen aplikasi dan layanan. Akan tetapi, jika Anda ingin agar layanan mengirimkan hasilnya kembali, maka |
| klien yang memulai layanan bisa membuat {@link android.app.PendingIntent} untuk siaran |
| (dengan {@link android.app.PendingIntent#getBroadcast getBroadcast()}) dan menyampaikannya ke layanan |
| dalam {@link android.content.Intent} yang memulai layanan. Layanan kemudian bisa menggunakan |
| siaran untuk menyampaikan hasil.</p> |
| |
| <p>Beberapa permintaan untuk memulai layanan menghasilkan beberapa panggilan pula ke |
| {@link android.app.Service#onStartCommand onStartCommand()} layanan. Akan tetapi, hanya satu permintaan untuk menghentikan |
| layanan (dengan {@link android.app.Service#stopSelf stopSelf()} atau {@link |
| android.content.Context#stopService stopService()}) dibutuhkan untuk menghentikannya.</p> |
| |
| |
| <h3 id="Stopping">Menghentikan layanan</h3> |
| |
| <p>Layanan yang sudah dimulai harus mengelola daur hidupnya sendiri. Artinya, sistem tidak menghentikan atau |
| memusnahkan layanan kecuali jika harus memulihkan memori sistem dan layanan |
| terus berjalan setelah {@link android.app.Service#onStartCommand onStartCommand()} kembali. Jadi, |
| layanan tersebut harus berhenti sendiri dengan memanggil {@link android.app.Service#stopSelf stopSelf()} atau |
| komponen lain bisa menghentikannya dengan memanggil {@link android.content.Context#stopService stopService()}.</p> |
| |
| <p>Setelah diminta untuk berhenti dengan {@link android.app.Service#stopSelf stopSelf()} atau {@link |
| android.content.Context#stopService stopService()}, sistem akan menghapus layanan |
| secepatnya.</p> |
| |
| <p>Akan tetapi, bila layanan Anda menangani beberapa permintaan ke {@link |
| android.app.Service#onStartCommand onStartCommand()} sekaligus, Anda tidak boleh menghentikan |
| layanan bila Anda baru selesai memproses permintaan memulai, karena setelah itu mungkin Anda sudah menerima permintaan memulai |
| yang baru (berhenti pada permintaan pertama akan menghentikan permintaan kedua). Untuk menghindari |
| masalah ini, Anda bisa menggunakan {@link android.app.Service#stopSelf(int)} untuk memastikan bahwa permintaan |
| Anda untuk menghentikan layanan selalu berdasarkan pada permintaan memulai terbaru. Artinya, bila Anda memanggil {@link |
| android.app.Service#stopSelf(int)}, Anda akan meneruskan ID permintaan memulai (<code>startId</code> |
| yang disampaikan ke {@link android.app.Service#onStartCommand onStartCommand()}) yang terkait dengan permintaan berhenti |
| Anda. Kemudian jika layanan menerima permintaan memulai baru sebelum Anda bisa memanggil {@link |
| android.app.Service#stopSelf(int)}, maka ID tidak akan sesuai dan layanan tidak akan berhenti.</p> |
| |
| <p class="caution"><strong>Perhatian:</strong> Aplikasi Anda perlu menghentikan layanannya |
| bila selesai bekerja untuk menghindari pemborosan sumber daya sistem dan tenaga baterai. Jika perlu, |
| komponen lain bisa menghentikan layanan secara eksplisit dengan memanggil {@link |
| android.content.Context#stopService stopService()}. Bahkan jika Anda mengaktifkan pengikatan bagi layanan, |
| Anda harus selalu menghentikan layanan sendiri jika layanan tersebut menerima panggilan ke {@link |
| android.app.Service#onStartCommand onStartCommand()}.</p> |
| |
| <p>Untuk informasi selengkapnya tentang daur hidup layanan, lihat bagian di bawah ini tentang <a href="#Lifecycle">Mengelola Daur Hidup Layanan</a>.</p> |
| |
| |
| |
| <h2 id="CreatingBoundService">Membuat Layanan Terikat</h2> |
| |
| <p>Layanan terikat adalah layanan yang memungkinkan komponen aplikasi untuk mengikatnya dengan memanggil {@link |
| android.content.Context#bindService bindService()} guna membuat koneksi yang berlangsung lama |
| (dan umumnya tidak mengizinkan komponen untuk <em>memulainya</em> dengan memanggil {@link |
| android.content.Context#startService startService()}).</p> |
| |
| <p>Anda sebaiknya membuat layanan terikat bila ingin berinteraksi dengan layanan dari aktivitas |
| dan komponen lain dalam aplikasi Anda atau mengeskpos sebagian fungsionalitas aplikasi Anda ke |
| ke aplikasi lain, melalui komunikasi antarproses (IPC).</p> |
| |
| <p>Untuk membuat layanan terikat, Anda harus mengimplementasikan metode callback {@link |
| android.app.Service#onBind onBind()} untuk mengembalikan {@link android.os.IBinder} yang |
| mendefinisikan antarmuka bagi komunikasi dengan layanan. Komponen aplikasi lain kemudian bisa memanggil |
| {@link android.content.Context#bindService bindService()} untuk mengambil antarmuka dan |
| mulai memanggil metode pada layanan. Layanan hanya hidup untuk melayani komponen aplikasi yang |
| terikat padanya, jadi bila tidak ada komponen yang terikat pada layanan, sistem akan memusnahkannya |
| (Anda <em>tidak</em> perlu menghentikan layanan terikat seperti halnya bila layanan dimulai |
| melalui {@link android.app.Service#onStartCommand onStartCommand()}).</p> |
| |
| <p>Untuk membuat layanan terikat, hal yang perlu dilakukan pertama kali adalah mendefinisikan antarmuka yang menetapkan |
| cara klien berkomunikasi dengan layanan. Antarmuka antara layanan |
| dan klien ini harus berupa implementasi {@link android.os.IBinder} dan yang harus dikembalikan |
| layanan Anda dari metode callback {@link android.app.Service#onBind |
| onBind()}. Setelah menerima {@link android.os.IBinder}, klien bisa mulai |
| berinteraksi dengan layanan melalui antarmuka tersebut.</p> |
| |
| <p>Beberapa klien bisa mengikat ke layanan sekaligus. Bila klien selesai berinteraksi dengan |
| layanan, klien akan memanggil {@link android.content.Context#unbindService unbindService()} untuk melepas ikatan. Bila |
| tidak ada klien yang terikat pada layanan, sistem akan menghapus layanan tersebut.</p> |
| |
| <p>Ada beberapa cara untuk mengimplementasikan layanan terikat dan implementasinya lebih |
| rumit daripada layanan yang sudah dimulai, jadi layanan terikat dibahas dalam dokumen |
| terpisah tentang <a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a>.</p> |
| |
| |
| |
| <h2 id="Notifications">Mengirim Pemberitahuan ke Pengguna</h2> |
| |
| <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> |
| |
| <p>Pemberitahuan Toast adalah pesan yang muncul sebentar pada permukaan jendela saat ini |
| kemudian menghilang, sementara pemberitahuan baris status memberikan ikon di baris status dengan |
| pesan yang bisa dipilih oleh pengguna untuk melakukan suatu tindakan (misalnya memulai suatu aktivitas).</p> |
| |
| <p>Biasanya, pemberitahuan baris status adalah teknik terbaik bila ada pekerjaan latar belakang yang sudah selesai |
| (misalnya file selesai |
| diunduh) dan pengguna kini bisa menggunakannya. Bila pengguna memilih pemberitahuan dari |
| tampilan diperluas, pemberitahuan akan bisa memulai aktivitas (misalnya menampilkan file yang baru diunduh).</p> |
| |
| <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> |
| untuk informasi selengkapnya.</p> |
| |
| |
| |
| <h2 id="Foreground">Menjalankan Layanan di Latar Depan</h2> |
| |
| <p>Layanan latar depan adalah layanan yang dianggap sebagai sesuatu yang |
| diketahui secara aktif oleh pengguna, jadi bukan sesuatu yang akan dihapus oleh sistem bila memori menipis. Sebuah |
| layanan latar depan harus memberikan pemberitahuan bagi baris status, yang ditempatkan pada |
| heading "Ongoing" yang artinya pemberitahuan tersebut tidak bisa diabaikan kecuali jika layanan |
| dihentikan atau dihapus dari latar depan.</p> |
| |
| <p>Misalnya, pemutar musik yang memutar musik dari suatu layanan harus diatur untuk berjalan di |
| latar depan, karena pengguna mengetahui operasi tersebut |
| secara eksplisit. Pemberitahuan di baris status bisa menunjukkan lagu saat ini dan memungkinkan |
| pengguna untuk menjalankan suatu aktivitas untuk berinteraksi dengan pemutar musik.</p> |
| |
| <p>Untuk meminta agar layanan Anda berjalan di latar depan, panggil {@link |
| android.app.Service#startForeground startForeground()}. Metode ini memerlukan dua parameter: sebuah integer |
| yang mengidentifikasi pemberitahuan secara unik dan {@link |
| android.app.Notification} untuk baris status. Misalnya:</p> |
| |
| <pre> |
| Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), |
| System.currentTimeMillis()); |
| Intent notificationIntent = new Intent(this, ExampleActivity.class); |
| PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); |
| notification.setLatestEventInfo(this, getText(R.string.notification_title), |
| getText(R.string.notification_message), pendingIntent); |
| startForeground(ONGOING_NOTIFICATION_ID, notification); |
| </pre> |
| |
| <p class="caution"><strong>Perhatian:</strong> ID integer yang Anda berikan ke {@link |
| android.app.Service#startForeground startForeground()} tidak boleh 0.</p> |
| |
| |
| <p>Untuk menghapus layanan dari latar depan, panggil {@link |
| android.app.Service#stopForeground stopForeground()}. Metode ini memerlukan boolean, yang menunjukkan |
| apakah pemberitahuan baris status juga akan dihapus. Metode ini <em>tidak</em> menghentikan |
| layanan. Akan tetapi, jika Anda menghentikan layanan saat masih berjalan di latar depan |
| maka pemberitahuan juga akan dihapus.</p> |
| |
| <p>Untuk informasi selengkapnya tentang pemberitahuan, lihat <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Membuat Pemberitahuan |
| Baris Status</a>.</p> |
| |
| |
| |
| <h2 id="Lifecycle">Mengelola Daur Hidup Layanan</h2> |
| |
| <p>Daur hidup layanan jauh lebih sederhana daripada daur hidup aktivitas. Akan tetapi, lebih penting lagi adalah |
| memerhatikan dengan cermat bagaimana layanan Anda dibuat dan dimusnahkan, karena suatu layanan |
| bisa berjalan di latar belakang tanpa disadari oleh pengguna.</p> |
| |
| <p>Daur hidup layanan—dari saat dibuat hingga dimusnahkan—bisa mengikuti |
| dua path berbeda:</p> |
| |
| <ul> |
| <li>Layanan yang sudah dimulai |
| <p>Layanan dibuat bila komponen lain memanggil {@link |
| android.content.Context#startService startService()}. Layanan kemudian berjalan terus-menerus dan harus |
| berhenti sendiri dengan memanggil {@link |
| android.app.Service#stopSelf() stopSelf()}. Komponen lain juga bisa menghentikan |
| layanan dengan memanggil {@link android.content.Context#stopService |
| stopService()}. Bila layanan dihentikan, sistem akan menghancurkannya.</p></li> |
| |
| <li>Layanan terikat |
| <p>Layanan dibuat bila komponen lain (klien) memanggil {@link |
| android.content.Context#bindService bindService()}. Klien kemudian berkomunikasi dengan layanan |
| melalui antarmuka {@link android.os.IBinder}. Klien bisa menutup koneksi dengan memanggil |
| {@link android.content.Context#unbindService unbindService()}. Sejumlah klien bisa mengikat pada |
| layanan yang sama dan bila semuanya melepas ikatan, sistem akan memusnahkan layanan tersebut. (Layanan |
| <em>tidak</em> perlu berhenti sendiri.)</p></li> |
| </ul> |
| |
| <p>Kedua path tersebut tidak benar-benar terpisah. Artinya, Anda bisa mengikat ke layanan yang sudah |
| dimulai dengan {@link android.content.Context#startService startService()}. Misalnya, layanan |
| musik latar belakang bisa dimulai dengan memanggil {@link android.content.Context#startService |
| startService()} dengan {@link android.content.Intent} yang mengidentifikasi musik yang akan diputar. Kemudian, |
| mungkin saat pengguna ingin mengontrol pemutar musik atau mendapatkan informasi |
| tentang lagu yang diputar, aktivitas bisa mengikat ke layanan dengan memanggil {@link |
| android.content.Context#bindService bindService()}. Dalam kasus seperti ini, {@link |
| android.content.Context#stopService stopService()} atau {@link android.app.Service#stopSelf |
| stopSelf()} tidak menghentikan layanan sampai semua klien melepas ikatan. </p> |
| |
| |
| <h3 id="LifecycleCallbacks">Mengimplementasikan callback daur hidup</h3> |
| |
| <p>Seperti halnya aktivitas, layanan memiliki metode callback daur hidup yang bisa Anda implementasikan |
| untuk memantau perubahan status layanan dan melakukan pekerjaan pada waktu yang tepat. Layanan skeleton |
| berikut memperagakan setiap metode daur hidup:</p> |
| |
| <pre> |
| public class ExampleService extends Service { |
| int mStartMode; // indicates how to behave if the service is killed |
| IBinder mBinder; // interface for clients that bind |
| boolean mAllowRebind; // indicates whether onRebind should be used |
| |
| @Override |
| public void {@link android.app.Service#onCreate onCreate}() { |
| // The service is being created |
| } |
| @Override |
| public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) { |
| // The service is starting, due to a call to {@link android.content.Context#startService startService()} |
| return <em>mStartMode</em>; |
| } |
| @Override |
| public IBinder {@link android.app.Service#onBind onBind}(Intent intent) { |
| // A client is binding to the service with {@link android.content.Context#bindService bindService()} |
| return <em>mBinder</em>; |
| } |
| @Override |
| public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) { |
| // All clients have unbound with {@link android.content.Context#unbindService unbindService()} |
| return <em>mAllowRebind</em>; |
| } |
| @Override |
| public void {@link android.app.Service#onRebind onRebind}(Intent intent) { |
| // A client is binding to the service with {@link android.content.Context#bindService bindService()}, |
| // after onUnbind() has already been called |
| } |
| @Override |
| public void {@link android.app.Service#onDestroy onDestroy}() { |
| // The service is no longer used and is being destroyed |
| } |
| } |
| </pre> |
| |
| <p class="note"><strong>Catatan:</strong> Tidak seperti metode callback daur hidup aktivitas, Anda |
| <em>tidak</em> perlu memanggil implementasi superkelas metode callback tersebut.</p> |
| |
| <img src="{@docRoot}images/service_lifecycle.png" alt="" /> |
| <p class="img-caption"><strong>Gambar 2.</strong> Daur hidup layanan. Diagram di sebelah kiri |
| menampilkan daur hidup bila layanan dibuat dengan {@link android.content.Context#startService |
| startService()} dan diagram di sebelah kanan menampilkan daur hidup bila layanan dibuat |
| dengan {@link android.content.Context#bindService bindService()}.</p> |
| |
| <p>Dengan mengimplementasikan metode-metode ini, Anda bisa memantau dua loop tersarang (nested loop) daur hidup layanan: </p> |
| |
| <ul> |
| <li><strong>Seluruh masa pakai</strong> layanan terjadi antara saat {@link |
| android.app.Service#onCreate onCreate()} dipanggil dan saat {@link |
| android.app.Service#onDestroy} kembali. Seperti halnya aktivitas, layanan melakukan penyiapan awal di |
| {@link android.app.Service#onCreate onCreate()} dan melepaskan semua sisa sumber daya yang ada di {@link |
| android.app.Service#onDestroy onDestroy()}. Misalnya, |
| layanan pemutar musik bisa membuat thread tempat musik akan diputar dalam {@link |
| android.app.Service#onCreate onCreate()}, kemudian menghentikan thread tersebut dalam {@link |
| android.app.Service#onDestroy onDestroy()}. |
| |
| <p>Metode {@link android.app.Service#onCreate onCreate()} dan {@link android.app.Service#onDestroy |
| onDestroy()} diperlukan semua layanan, baik yang |
| dibuat oleh {@link android.content.Context#startService startService()} maupun {@link |
| android.content.Context#bindService bindService()}.</p></li> |
| |
| <li><strong>Masa pakai aktif</strong> layanan dimulai dengan panggilan ke {@link |
| android.app.Service#onStartCommand onStartCommand()} atau {@link android.app.Service#onBind onBind()}. |
| Masing-masing metode diberikan {@link |
| android.content.Intent} yang diteruskan ke {@link android.content.Context#startService |
| startService()} atau {@link android.content.Context#bindService bindService()}. |
| <p>Jika layanan telah dimulai, masa pakai aktif akan berakhir pada saat yang sama dengan |
| berakhirnya seluruh masa pakai (layanan masih aktif bahkan setelah {@link android.app.Service#onStartCommand |
| onStartCommand()} kembali). Jika layanan tersebut terikat, masa pakai aktifnya akan berakhir bila {@link |
| android.app.Service#onUnbind onUnbind()} kembali.</p> |
| </li> |
| </ul> |
| |
| <p class="note"><strong>Catatan:</strong> Meskipun layanan yang sudah dimulai dihentikan dengan panggilan ke |
| {@link android.app.Service#stopSelf stopSelf()} atau {@link |
| android.content.Context#stopService stopService()}, tidak ada callback tersendiri bagi |
| layanan tersebut (tidak ada callback {@code onStop()}). Jadi, kecuali jika layanan terikat ke klien, |
| sistem akan memusnahkannya bila layanan dihentikan—{@link |
| android.app.Service#onDestroy onDestroy()} adalah satu-satunya callback yang diterima.</p> |
| |
| <p>Gambar 2 mengilustrasikan metode callback yang lazim bagi suatu layanan. Walaupun gambar tersebut memisahkan |
| layanan yang dibuat oleh {@link android.content.Context#startService startService()} dari layanan |
| yang dibuat oleh {@link android.content.Context#bindService bindService()}, ingatlah |
| bahwa suatu layanan, bagaimana pun dimulainya, bisa memungkinkan klien mengikat padanya. |
| Jadi, suatu layanan yang awalnya dimulai dengan {@link android.app.Service#onStartCommand |
| onStartCommand()} (oleh klien yang memanggil {@link android.content.Context#startService startService()}) |
| masih bisa menerima panggilan ke {@link android.app.Service#onBind onBind()} (bila klien memanggil |
| {@link android.content.Context#bindService bindService()}).</p> |
| |
| <p>Untuk informasi selengkapnya tentang membuat layanan yang menyediakan pengikatan, lihat dokumen <a href="{@docRoot}guide/components/bound-services.html">Layanan Terikat</a>, |
| yang menyertakan informasi selengkapnya tentang metode callback {@link android.app.Service#onRebind onRebind()} |
| di bagian tentang <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">Mengelola Daur Hidup |
| Layanan Terikat</a>.</p> |
| |
| |
| <!-- |
| <h2>Beginner's Path</h2> |
| |
| <p>To learn how to query data from the system or other applications (such as contacts or media |
| stored on the device), continue with the <b><a |
| href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b> |
| document.</p> |
| --> |