Ringkasan proses dan thread

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:

  1. Jangan memblokir UI thread.
  2. 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.