Saat komponen aplikasi dimulai dan aplikasi tidak memiliki komponen lain berjalan, sistem Android akan memulai proses Linux baru untuk aplikasi dengan satu thread dalam proses eksekusi. Secara {i>default<i}, semua komponen aplikasi yang sama berjalan dalam proses dan thread yang sama, yang disebut thread utama.
Jika komponen aplikasi dimulai dan sudah ada proses untuk aplikasi itu, karena komponen lain dari aplikasi sudah dimulai, maka komponen dimulai di dalam proses itu dan menggunakan thread eksekusi yang sama. Namun, Anda dapat mengatur komponen yang berbeda di aplikasi Anda untuk berjalan di proses terpisah, dan Anda bisa membuat {i>thread<i} untuk proses apa pun.
Dokumen ini membahas cara kerja proses dan thread di aplikasi Android.
Proses
Secara {i>default<i}, semua komponen aplikasi berjalan dalam proses yang sama, dan sebagian besar aplikasi jangan ubah ini. Namun, jika Anda merasa perlu mengontrol proses mana yang milik Anda, Anda dapat melakukannya di file manifes.
Entri manifes untuk setiap jenis elemen komponen—<activity>
, <service>
, <receiver>
, dan <provider>
—mendukung atribut android:process
yang dapat menentukan
tempat komponen berjalan. Anda dapat menyetel atribut ini agar setiap komponen berjalan
dalam prosesnya sendiri atau sehingga beberapa komponen
memiliki proses yang sama sementara yang lain tidak.
Anda juga dapat mengatur
android:process
agar komponen aplikasi yang berbeda berjalan di
selama aplikasi berbagi ID pengguna Linux yang sama dan ditandatangani dengan
sertifikat yang sama.
<application>
juga mendukung atribut android:process
, yang dapat Anda gunakan untuk menyetel
nilai default yang berlaku untuk semua komponen.
Android mungkin memutuskan untuk menghentikan proses pada saat sumber daya diperlukan oleh proses lain yang lebih cepat melayani pengguna. Penerapan komponen yang berjalan dalam proses yang dimatikan juga dihancurkan. Proses dimulai sekali lagi untuk komponen-komponen itu ketika ada pekerjaan untuk mereka lakukan.
Saat memutuskan proses mana yang akan dimatikan, sistem Android akan mempertimbangkan kepentingan relatifnya terhadap pengguna. Misalnya, ia lebih mudah mematikan proses hosting aktivitas yang tidak lagi terlihat di layar, dibandingkan dengan proses yang menghosting aktivitas yang terlihat. Keputusan apakah akan menghentikan proses, oleh karena itu, tergantung pada status komponen yang berjalan dalam proses itu.
Detail siklus hidup proses dan hubungannya dengan status aplikasi dibahas di Proses dan siklus proses aplikasi.
Thread
Saat aplikasi diluncurkan, sistem akan membuat thread eksekusi untuk aplikasi tersebut,
yang disebut thread utama. Thread ini sangat penting, karena bertugas mengirim peristiwa ke
widget antarmuka pengguna yang sesuai, termasuk peristiwa menggambar. Ini juga
hampir selalu thread tempat aplikasi Anda berinteraksi dengan komponen
dari android.widget
dan toolkit UI Android
android.view
paket.
Karena alasan ini, thread utama terkadang
yang disebut UI thread. Namun, dalam keadaan khusus, elemen
thread mungkin bukan thread UI-nya. Untuk informasi selengkapnya, lihat Rangkaian pesan
anotasi.
Sistem tidak membuat thread terpisah untuk setiap instance komponen. Semua
komponen yang berjalan di proses yang sama dibuat instance-nya dalam thread UI, dan sistem memanggil
setiap komponen dikirim dari thread itu. Akibatnya, metode yang merespons sistem
callback—seperti onKeyDown()
untuk melaporkan tindakan pengguna, atau metode callback siklus proses—selalu jalankan di UI thread proses.
Misalnya, saat pengguna menyentuh tombol pada layar, UI thread aplikasi Anda akan mengirimkan peristiwa sentuh ke widget, yang kemudian menyetel status ditekan dan memposting permintaan yang tidak divalidasi ke antrean peristiwa. UI thread menghapus antrean permintaan dan memberi tahu widget untuk menggambar ulang itu sendiri.
Kecuali Anda mengimplementasikan aplikasi dengan benar, model thread tunggal ini bisa menghasilkan kinerja yang buruk ketika aplikasi melakukan pekerjaan intensif sebagai respons terhadap interaksi pengguna. Melakukan operasi panjang di thread UI, seperti akses jaringan atau kueri {i>database<i}, memblokir seluruh UI. Jika thread diblokir, tidak ada peristiwa yang bisa dikirim, termasuk peristiwa menggambar.
Dari sudut pandang pengguna, aplikasi tampak hang. Lebih buruk lagi, jika UI thread diblokir selama lebih dari beberapa detik, pengguna akan diberikan pesan "aplikasi yang merespons" (ANR). Pengguna kemudian mungkin memutuskan untuk keluar dari aplikasi Anda atau bahkan meng-uninstal anotasi.
Perlu diingat bahwa toolkit UI Android tidak aman untuk thread. Jadi, jangan memanipulasi UI Anda dari thread pekerja. Melakukan semua manipulasi pada antarmuka pengguna dari UI . Ada dua aturan untuk model thread tunggal Android:
- Jangan memblokir UI thread.
- Jangan mengakses toolkit UI Android dari luar UI thread.
Thread pekerja
Karena model thread tunggal ini, sangat penting untuk UI aplikasi yang tidak Anda blokir UI threadnya. Jika Anda memiliki operasi untuk dilakukan yang tidak instan, pastikan untuk melakukannya di latar belakang terpisah atau pekerja. Ingatlah bahwa Anda tidak dapat memperbarui UI dari thread apa pun selain UI, atau thread utama.
Untuk membantu Anda mengikuti aturan ini, Android menawarkan beberapa cara untuk mengakses UI thread dari . Berikut ini daftar metode yang bisa membantu:
Contoh berikut menggunakan View.post(Runnable)
:
Kotlin
fun onClick(v: View) { Thread(Runnable { // A potentially time consuming task. val bitmap = processBitMap("image.png") imageView.post { imageView.setImageBitmap(bitmap) } }).start() }
Java
public void onClick(View v) { new Thread(new Runnable() { public void run() { // A potentially time consuming task. final Bitmap bitmap = processBitMap("image.png"); imageView.post(new Runnable() { public void run() { imageView.setImageBitmap(bitmap); } }); } }).start(); }
Implementasi ini aman untuk thread, karena operasi latar belakang dilakukan dari thread terpisah
sementara ImageView
selalu dimanipulasi dari UI thread.
Namun, ketika operasi semakin kompleks, kode seperti ini bisa semakin rumit dan
sulit dikelola. Untuk menangani interaksi yang lebih kompleks dengan thread pekerja, Anda dapat mempertimbangkan
menggunakan Handler
di thread pekerja Anda
untuk memproses pesan yang
dikirim dari UI thread. Untuk penjelasan lengkap
tentang cara
menjadwalkan pekerjaan pada thread latar belakang dan berkomunikasi kembali ke UI thread, lihat
Ringkasan Pekerjaan Latar Belakang.
Metode thread-safe
Dalam beberapa situasi, metode yang Anda implementasikan dipanggil dari lebih dari satu thread, dan oleh karena itu harus ditulis agar aman untuk thread.
Hal ini terutama berlaku untuk metode yang dapat dipanggil dari jarak jauh, seperti metode dalam layanan terikat. Saat panggilan di
yang diterapkan dalam IBinder
berasal dari proses yang sama dengan
IBinder
sedang berjalan, metode ini dieksekusi di thread pemanggil.
Namun, jika panggilan berasal dari proses lain, metode akan dieksekusi dalam thread yang dipilih dari
kumpulan thread yang dikelola sistem dalam proses yang sama dengan IBinder
.
Fungsi ini tidak dijalankan di thread UI proses.
Misalnya, sementara atribut
Metode onBind()
dipanggil dari UI thread
proses layanan, metode yang diterapkan dalam objek yang ditampilkan onBind()
, seperti
yang mengimplementasikan metode panggilan prosedur jarak jauh (RPC), dipanggil dari thread
di kolam renang. Karena layanan dapat memiliki lebih dari satu klien, lebih dari satu thread kumpulan dapat berinteraksi
metode IBinder
yang sama sekaligus, sehingga metode IBinder
harus
agar aman untuk thread.
Demikian pula, penyedia materi bisa menerima permintaan data yang berasal dari proses lain.
ContentResolver
dan ContentProvider
menyembunyikan detail bagaimana
komunikasi antarproses (IPC) dikelola,
tetapi metode ContentProvider
yang merespons permintaan tersebut—metode
query()
,
insert()
,
delete()
,
update()
,
dan getType()
—merupakan
dipanggil dari kumpulan thread dalam proses penyedia konten, bukan UI
thread untuk proses tersebut. Karena metode ini mungkin dipanggil
dari sejumlah thread mana pun di
pada saat yang sama, keduanya juga harus
diimplementasikan agar aman untuk thread.
Komunikasi antar-proses
Android menawarkan mekanisme untuk IPC dengan menggunakan RPC, yang mana metode ini dipanggil oleh aktivitas atau aplikasi lain tetapi dijalankan dari jarak jauh dalam proses lain, dengan hasil apa pun dikembalikan ke penelepon. Fungsi ini memerlukan penguraian panggilan metode dan datanya ke tingkat yang bisa dilakukan sistem operasi memahami, mentransmisikannya dari proses lokal dan ruang alamat ke proses jarak jauh dan ruang alamat, dan kemudian menyusun kembali dan mengulangi panggilan di sana.
Nilai yang ditampilkan kemudian ditransmisikan dalam arah yang berlawanan. Android menyediakan semua kode untuk melakukan IPC ini transaksi, sehingga Anda dapat berfokus pada pendefinisian dan penerapan antarmuka pemrograman RPC.
Untuk melakukan IPC, aplikasi Anda harus diikat ke layanan menggunakan bindService()
. Untuk mengetahui informasi selengkapnya, lihat Ringkasan layanan.