7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. Android SDK

Konkurensi Praktis di Android dengan HaMeR

Read Time: 14 mins

Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)

Dalam Memahami Konkurensi di Android Menggunakan HaMeR, kita membahas dasar-dasar kerangka kerja HaMeR (Handler, Message, dan Runnable). Kita membahas opsinya, begitu juga kapan dan bagaimana cara menggunakannya.

Hari ini, kita akan membuat aplikasi sederhana untuk mengeksplorasi konsep yang telah dipelajari. Dengan pendekatan langsung, kita akan melihat bagaimana menerapkan berbagai kemungkinan HaMeR dalam mengelola konkurensi di Android.

1. Aplikasi Sampel

Mari kita bekerja dan mengirim beberapa Runnable dan mengirim objek Message pada aplikasi sampel. Untuk membuatnya sesederhana mungkin, kita akan mengeksplorasi bagian-bagian yang paling menarik. Semua file sumber daya dan activity standar akan diabaikan di sini. Jadi saya sangat menyarankan Anda untuk memeriksa kode sumber dari aplikasi sampel dengan komentar ekstensifnya.

HaMeR sample applicationHaMeR sample applicationHaMeR sample application

Aplikasi ini terdiri dari:

  • Dua activities, satu untuk Runnable lainnya untuk panggilan Message
  • Dua objek HandlerThread:
    • WorkerThread untuk menerima dan memproses panggilan dari UI
    • CounterThread untuk menerima Message dari WorkerThread
  • Beberapa kelas utilitas (untuk menyimpan objek selama perubahan konfigurasi dan untuk layout)

2. Posting dan Menerima Runnables

Mari mulai bereksperimen dengan metode Handler.post(Runnable) dan variasinya, yang menambahkan runnable ke MessageQueue yang terkait dengan sebuah thread. Kita akan membuat sebuah activity bernama RunnableActivity, yang berkomunikasi dengan thread latar belakang yang disebut WorkerThread.

RunnableActivity menginstansiasi sebuah thread latar belakang yang disebut WorkerThread, mengirimkan Handler dan sebuah WorkerThread.Callback sebagai parameter. Activity tersebut dapat membuat panggilan ke WorkerThread untuk mengunduh bitmap secara asinkron dan mempertunjukkannya pada waktu tertentu. Hasil tugas yang dilakukan oleh thread worker dikirim ke RunnableActivity oleh runnable yang diposkan di Handler yang diterima oleh WorkerThread.

2.1 Mempersiapkan Handler untuk RunnableActivity

Pada RunnableActivity kita akan membuat Handler untuk dikirimkan ke WorkerThread. uiHandler akan dikaitkan dengan Looper dari thread UI, karena dipanggil dari thread itu.

2.2 Mendeklarasikan WorkerThread dan Antarmuka Callback-nya

WorkerThread adalah thread latar dimana kita akan memulai berbagai jenis tugas. Ini berkomunikasi dengan antarmuka pengguna menggunakan responseHandler dan antarmuka callback yang diterima selama instansiasinya. Referensi yang diterima dari activity tersebut adalah tipe WeakReference<>, karena suatu activity dapat dihancurkan dan rujukannya hilang.

Kelasnya menawarkan antarmuka yang bisa diimplementasikan oleh UI. Ini juga memperluas HandlerThread, kelas helper yang dibangun di atas Thread yang sudah berisi Looper, dan MessageQueue. Karena itu memiliki setup yang benar untuk menggunakan kerangka kerja HaMeR.

2.3 Inisialisasi WorkerThread

Kita perlu menambahkan metode ke WorkerThread untuk dipanggil oleh activity yang menyiapkan postHandler dari thread untuk digunakan. Metode ini perlu dipanggil hanya setelah thread dimulai.

Pada RunnableActivity kita harus mengimplementasikan WorkerThread.Callback dan menginisialisasi thread sehingga bisa digunakan.

2.4 Menggunakan Handler.post() di WorkerThread

Metode WorkerThread.downloadWithRunnable() mengunduh bitmap dan mengirimkannya ke RunnableActivity untuk ditampilkan dalam View gambar. Ini menggambarkan dua penggunaan dasar perintah Handler.post(Runnable run):

  • Mengizinkan Thread agar memposkan objek Runnable ke MessageQueue yang terkait dengan dirinya sendiri saat .post() dipanggil pada Handler yang terkait dengan Looper Thread.
  • Memungkinkan komunikasi dengan Thread lain, ketika .post() dipanggil pada Handler yang terkait dengan Looper Thread lainnya.
  1. Metode WorkerThread.downloadWithRunnable() memposkan sebuah Runnable ke MessageQueue dari WorkerThread menggunakan postHandler, sebuah Handler yang terkait dengan Looper WorkThread.
  2. Saat runnable diproses, ia mengunduh Bitmap di WorkerThread.
  3. Setelah bitmap diunduh, responseHandler, handler yang terkait dengan thread UI, digunakan untuk memposting runnable pada RunnableActivity yang berisi bitmap.
  4. Runnable diproses, dan WorkerThread.Callback.loadImage digunakan untuk mempertunjukkan gambar yang diunduh pada ImageView.

2.5 Menggunakan Handler.postAtTime() dan Activity.runOnUiThread()

WorkerThread.toastAtTime() menjadwalkan tugas yang akan dijalankan pada waktu tertentu, menunjukkan Toast kepada pengguna. Metode ini menggambarkan penggunaan Handler.postAtTime() dan Activity.runOnUiThread().

  • Handler.postAtTime(Runnable run, long uptimeMillis) memposting sebuah runnable pada waktu tertentu.
  • Activity.runOnUiThread(Runnable run) menggunakan handler UI default untuk memposting sebuah runnable ke thread utama.

3. Mengirim Pesan dengan MessageActivity & WorkerThread

Selanjutnya, mari menjelajahi beberapa cara yang berbeda untuk menggunakan MessageActivity untuk mengirim dan memproses objek Message. MessageActivity menginstansiasi WorkerThread, mengirimkan Handler sebagai parameter. WorkerThread memiliki beberapa metode public dengan tugas yang harus dipanggil oleh activity untuk mengunduh bitmap, mengunduh bitmap acak, atau menunjukkan Toast setelah beberapa waktu yang tertunda. Hasil semua operasi tersebut dikirim kembali ke MessageActivity dengan menggunakan objek Message yang dikirim oleh responseHandler.

3.1 Mempersiapkan Handler Respon dari MessageActivity

Seperti dalam RunnableActivity, dalam MessageActivity kita harus menginstansiasi dan menginisialisasi WorkerThread yang mengirimkan Handler untuk menerima data dari thread latar belakang. Namun, kali ini kita tidak akan mengimplementasikan WorkerThread.Callback; sebagai gantinya, kita akan menerima tanggapan dari WorkerThread secara eksklusif oleh objek Message.

Karena sebagian besar kode MessageActivity and RunnableActivity pada dasarnya sama, kita hanya akan berkonsentrasi pada persiapan uiHandler, yang akan dikirim ke WorkerThread untuk menerima pesan darinya.

Pertama, mari kita berikan beberapa kunci int untuk digunakan sebagai pengidentifikasi ke objek Message.

Pada implementasi MessageHandler, kita harus memperluas Handler dan menerapkan metode handleMessage(Message), dimana semua pesan akan diproses. Perhatikan bahwa kami mengambil Message.what untuk mengidentifikasi pesannya, dan kami juga mendapatkan berbagai jenis data dari Message.obj. Mari meninjau dengan cepat properti Message yang terpenting sebelum masuk ke kodenya.

  • Message.what: int mengidentifikasi Message
  • Message.arg1: int argumen bebas
  • Message.arg2: int argumen bebas
  • Message.obj: Object untuk menyimpan berbagai jenis data

3.2 Mengirim Pesan dengan WorkerThread

Sekarang mari kita kembali ke kelas WorkerThread. Kita akan menambahkan beberapa kode untuk mengunduh bitmap tertentu dan juga kode untuk mengunduh yang acak. Untuk menyelesaikan tugas tersebut, kita akan mengirim objek Message dari WorkerThread ke dirinya sendiri dan mengirimkan hasilnya kembali ke MessageActivity dengan menggunakan logika yang sama persis yang diterapkan sebelumnya untuk RunnableActivity.

Pertama, kita perlu memperpanjang Handler untuk memproses pesan yang diunduh.

Metode downloadImageMSG(String url) pada dasarnya sama dengan metode downloadImage(String url). Satu-satunya perbedaan adalah bahwa yang pertama mengirimkan bitmap yang diunduh kembali ke UI dengan mengirim pesan menggunakan responseHandler.

LoadImageOnUIMSG(Bitmap image) bertanggung jawab untuk mengirim pesan dengan bitmap yang diunduh ke MessageActivity.

Perhatikan bahwa alih-alih membuat objek Message dari awal, kita menggunakan metode Handler.obtainMessage(int what, Object obj) untuk mengambil Message dari pool global, yang menghemat beberapa sumber daya. Penting juga untuk dicatat bahwa kita memanggil obtainMessage() pada responseHandler, mendapatkan Message yang terkait dengan Looper dari MessageActivity. Ada dua cara untuk mengambil Message dari pool global: Message.obtain() dan Handler.obtainMessage().

Satu-satunya yang tersisa untuk dilakukan pada tugas mengunduh gambar adalah menyediakan metode untuk mengirim Message ke WorkerThread untuk memulai proses pengunduhan. Perhatikan bahwa kali ini kita akan memanggil Message.obtain(Handler handler, int what, Object obj) pada handlerMsgImgDownloader, mengaitkan pesan tersebut dengan looper WorkerThread.

Kemungkinan lain yang menarik adalah mengirim objek Message untuk diproses di lain waktu dengan perintah Message.sendMessageDelayed(Message msg, long timeMillis).

Kami membuat Handler secara tegas untuk mengirimkan pesan yang tertunda. Alih-alih memperluas kelas Handler, kami mengambil rute menginstansiasi Handler dengan menggunakan antarmuka Handler.Callback, yang menerapkan metode handleMessage(Message msg) untuk memproses Message yang tertunda.

4. Kesimpulan

Sekarang Anda sudah melihat kode yang cukup untuk memahami bagaimana menerapkan konsep kerangka kerja HaMeR dasar untuk mengelola konkurensi di Android. Ada beberapa fitur menarik lainnya dari proyek akhir yang tersimpan di GitHub, dan saya sangat menyarankan Anda untuk memeriksanya.

Akhirnya, saya memiliki beberapa pertimbangan terakhir yang harus Anda ingat:

  • Jangan lupa mempertimbangkan siklus hidup Activity Android saat bekerja dengan HaMeR dan Threads secara umum. Jika tidak, aplikasi Anda mungkin gagal saat thread mencoba mengakses activity yang telah dihancurkan karena perubahan konfigurasi atau karena alasan lain. Solusi yang umum adalah menggunakan RetainedFragment untuk menyimpan thread dan mengisi thread latar belakang dengan referensi activity setiap kali activity dihancurkan. Lihatlah solusinya di proyek akhir di GitHub.
  • Tugas yang dijalankan karena objek Runnable dan Message yang diproses pada Handlers tidak berjalan asinkron. Mereka akan berjalan sinkron di thread yang terkait dengan handler. Agar asinkron, Anda perlu membuat thread lain, mengirim/memposting objek Message/Runnable di atasnya, dan menerima hasilnya pada waktu yang tepat.

Seperti yang Anda lihat, kerangka kerja HaMeR memiliki banyak kemungkinan yang berbeda, dan ini adalah solusi yang cukup terbuka dengan banyak pilihan untuk mengelola konkurensi di Android. Karakteristik ini bisa menjadi keunggulan dibanding AsyncTask, tergantung kebutuhan Anda. Jelajahi lebih banyak kerangka kerja dan baca dokumentasinya, dan Anda akan menciptakan hal-hal hebat dengannya.

Sampai jumpa lagi!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Scroll to top
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.