Sedikit variasi pada postingan saya yang lain
Pada dasarnya saya memiliki pesan Handler
di saya Fragment
yang menerima banyak pesan yang dapat mengakibatkan dialog ditutup atau ditampilkan.
Ketika aplikasi diletakkan di latar belakang saya mendapatkan onPause
tapi kemudian masih mendapatkan pesan saya datang seperti yang diharapkan. Namun, karena saya menggunakan fragmen, saya tidak bisa begitu saja mengabaikan dan menampilkan dialog karena itu akan menghasilkan file IllegalStateException
.
Saya tidak bisa begitu saja mengabaikan atau membatalkan membiarkan kerugian negara.
Mengingat bahwa saya memiliki, Handler
saya bertanya-tanya apakah ada pendekatan yang disarankan tentang bagaimana saya harus menangani pesan saat dalam keadaan jeda.
Salah satu solusi yang mungkin saya pertimbangkan adalah merekam pesan yang masuk saat dijeda dan memutarnya kembali di onResume
. Ini agak tidak memuaskan dan saya berpikir pasti ada sesuatu dalam kerangka kerja untuk menangani ini dengan lebih elegan.
Jawaban:
Meskipun sistem operasi Android tampaknya tidak memiliki mekanisme yang cukup untuk mengatasi masalah Anda, saya yakin pola ini memberikan solusi yang relatif sederhana untuk diterapkan.
Kelas berikut adalah pembungkus
android.os.Handler
yang mendukung pesan ketika sebuah aktivitas dijeda dan memutarnya kembali pada resume.Pastikan kode apa pun yang Anda miliki yang secara asinkron mengubah status fragmen (mis. Komit, tutup) hanya dipanggil dari pesan di penangan.
Turunkan pawang Anda dari
PauseHandler
kelas.Setiap kali aktivitas Anda menerima
onPause()
panggilanPauseHandler.pause()
danonResume()
panggilanPauseHandler.resume()
.Gantilah implementasi Handler Anda
handleMessage()
denganprocessMessage()
.Memberikan implementasi sederhana
storeMessage()
yang selalu kembalitrue
.Di bawah ini adalah contoh sederhana bagaimana
PausedHandler
kelas dapat digunakan.Dengan mengklik tombol, pesan tertunda dikirim ke penangan.
Saat penangan menerima pesan (di thread UI), ini akan menampilkan
DialogFragment
.Jika
PausedHandler
kelas tidak digunakan, IllegalStateException akan ditampilkan jika tombol beranda ditekan setelah menekan tombol uji untuk meluncurkan dialog.Saya telah menambahkan
storeMessage()
metode kePausedHandler
kelas jika ada pesan yang harus segera diproses bahkan ketika aktivitas dihentikan sementara. Jika pesan ditangani maka false harus dikembalikan dan pesan tersebut akan dibuang.sumber
resume
metode yang digunakan secarasendMessage(msg)
teknis mungkin ada utas lain yang mengantre pesan tepat sebelum (atau di antara iterasi loop), yang berarti bahwa pesan yang disimpan dapat disisipkan dengan pesan baru yang tiba. Tidak yakin apakah itu masalah besar. Mungkin menggunakansendMessageAtFrontOfQueue
(dan tentu saja melakukan iterasi ke belakang) akan menyelesaikan masalah ini?Versi PauseHandler yang sangat baik dari quickdraw yang sedikit lebih sederhana adalah
Itu mengasumsikan bahwa Anda selalu ingin menyimpan pesan offline untuk diputar ulang. Dan memberikan Activity sebagai input
#processMessages
agar Anda tidak perlu mengelolanya di sub class.sumber
resume()
danpause()
, danhandleMessage
synchronized
?Berikut adalah cara yang sedikit berbeda untuk mendekati masalah melakukan Fragment yang dilakukan dalam fungsi callback dan menghindari masalah IllegalStateException.
Pertama buat antarmuka yang dapat dijalankan kustom.
Selanjutnya, buat fragmen untuk memproses objek MyRunnable. Jika objek MyRunnable dibuat setelah Aktivitas dihentikan sementara, misalnya jika layar diputar, atau pengguna menekan tombol beranda, itu akan dimasukkan ke dalam antrian untuk diproses nanti dengan konteks baru. Antrian bertahan dari perubahan konfigurasi apa pun karena instance setRetain disetel ke true. Metode runProtected dijalankan pada UI thread untuk menghindari kondisi balapan dengan tanda isPaused.
Akhirnya, fragmen dapat digunakan dalam aplikasi utama sebagai berikut:
sumber
Dalam proyek saya, saya menggunakan pola desain pengamat untuk menyelesaikannya. Di Android, penerima siaran dan maksud adalah implementasi dari pola ini.
Apa yang saya lakukan adalah membuat BroadcastReceiver yang saya mendaftar di fragmen / kegiatan ini onResume dan unregister di fragmen / kegiatan ini onPause . Dalam BroadcastReceiver metode 's onReceive Aku meletakkan semua kode yang kebutuhan untuk menjalankan sebagai akibat dari - BroadcastReceiver yang - menerima Intent (pesan) yang dikirim ke aplikasi Anda secara umum. Untuk meningkatkan selektivitas pada tipe maksud apa yang bisa diterima fragmen Anda, Anda bisa menggunakan filter maksud seperti pada contoh di bawah ini.
Keuntungan dari pendekatan ini adalah Intent (pesan) bisa dikirim dari mana saja di dalam aplikasi Anda (dialog yang terbuka di atas fragmen Anda, tugas asinkron, fragmen lain, dll.). Parameter bahkan bisa diteruskan sebagai ekstra maksud.
Keuntungan lainnya adalah pendekatan ini kompatibel dengan versi Android API apa pun, karena BroadcastReceivers dan Intents telah diperkenalkan pada API level 1.
Anda tidak perlu menyiapkan izin khusus apa pun pada file manifes aplikasi Anda kecuali jika Anda berencana menggunakan sendStickyBroadcast (di mana Anda perlu menambahkan BROADCAST_STICKY).
sumber