Saya mengubah kode saya dari menggunakan Handler
menjadi AsyncTask
. Yang terakhir sangat bagus dalam fungsinya - pembaruan asinkron dan penanganan hasil di utas UI utama. Apa yang tidak jelas bagi saya adalah bagaimana menangani pengecualian jika ada masalah AsyncTask#doInBackground
.
Cara saya melakukannya adalah memiliki Handler kesalahan dan mengirim pesan ke sana. Ini berfungsi dengan baik, tetapi apakah itu pendekatan yang "benar" atau adakah alternatif yang lebih baik?
Saya juga mengerti bahwa jika saya mendefinisikan Handler kesalahan sebagai bidang Kegiatan, itu harus dijalankan di utas UI. Namun, kadang-kadang (sangat tidak terduga) saya akan mendapatkan Pengecualian yang mengatakan bahwa kode yang dipicu dari Handler#handleMessage
mengeksekusi di utas yang salah. Haruskah saya menginisialisasi Handler kesalahan Activity#onCreate
sebagai gantinya? Menempatkan runOnUiThread
ke dalam Handler#handleMessage
tampaknya berlebihan tetapi dijalankan dengan sangat andal.
Jawaban:
Saya berpegang pada
Throwable
atauException
dalamAsyncTask
instance itu sendiri dan kemudian melakukan sesuatu dengan ituonPostExecute()
, sehingga penanganan kesalahan saya memiliki opsi untuk menampilkan dialog di layar.sumber
AsyncTask
pola berikut yang saya jelaskan.Buat objek AsyncResult (yang juga dapat Anda gunakan dalam proyek lain)
Kembalikan objek ini dari metode AsyncTask doInBackground Anda dan periksa di postExecute. (Anda dapat menggunakan kelas ini sebagai kelas dasar untuk tugas async Anda yang lain)
Di bawah ini adalah mockup tugas yang mendapat respons JSON dari server web.
sumber
super()
diAsyncTaskResult
saat kelas tidak memperpanjang apa-apa?Ketika saya merasa perlu menangani Pengecualian
AsyncTask
dengan benar, saya menggunakan ini sebagai kelas super:Seperti biasa, Anda mengganti
doInBackground
subclass Anda untuk melakukan pekerjaan latar belakang, dengan senang hati melempar Pengecualian di mana diperlukan. Anda kemudian dipaksa untuk mengimplementasikanonPostExecute
(karena abstrak) dan ini dengan lembut mengingatkan Anda untuk menangani semua jenisException
, yang dilewatkan sebagai parameter. Dalam kebanyakan kasus, Pengecualian menyebabkan beberapa jenis output ui, jadionPostExecute
merupakan tempat yang sempurna untuk melakukan itu.sumber
params
, jadi lebih mirip dengan yang asli dan lebih mudah untuk dimigrasi?new Task("Param").execute()
lebihnew Task().execute("Param")
.Jika Anda ingin menggunakan kerangka kerja RoboGuice yang memberi Anda manfaat lain, Anda dapat mencoba RoboAsyncTask yang memiliki Callback tambahan padaException (). Bekerja sangat bagus dan saya menggunakannya. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
sumber
RoboGuice
masih hidup? Tampaknya belum diperbarui sejak 2012?Saya membuat subkelas AsyncTask saya sendiri dengan antarmuka yang menentukan panggilan balik untuk keberhasilan dan kegagalan. Jadi jika pengecualian dilemparkan ke AsyncTask Anda, fungsi onFailure akan melewati pengecualian, jika tidak, panggilan balik onSuccess akan melewati hasil Anda. Mengapa android tidak memiliki sesuatu yang lebih baik tersedia di luar saya.
sumber
Solusi yang lebih komprehensif untuk solusi Cagatay Kalan ditunjukkan di bawah ini:
AsyncTaskResult
ExceptionHandlingAsyncTask
Contoh Tugas
sumber
Kelas sederhana ini dapat membantu Anda
sumber
Cara lain yang tidak bergantung pada berbagi anggota variabel adalah menggunakan pembatalan.
Ini dari dokumen Android:
Jadi, Anda dapat memanggil batal dalam pernyataan tangkap dan pastikan onPostExcute tidak pernah dipanggil, tetapi sebaliknya onCancelled dipanggil pada utas UI. Jadi, Anda dapat menampilkan pesan kesalahan.
sumber
cancel(boolean)
menghasilkan panggilan untukonCancelled()
ada sejak awal, tetapionCancelled(Result)
ditambahkan di API 11 .Sebenarnya, AsyncTask menggunakan FutureTask & Executor, FutureTask mendukung rantai pengecualian Pertama mari kita mendefinisikan kelas pembantu
Kedua, mari kita gunakan
sumber
Secara pribadi, saya akan menggunakan pendekatan ini. Anda bisa menangkap pengecualian dan mencetak jejak tumpukan jika Anda membutuhkan info.
buat tugas Anda di latar belakang mengembalikan nilai boolean.
seperti ini:
sumber
Kemungkinan lain akan digunakan
Object
sebagai tipe kembali, dan dionPostExecute()
periksa untuk jenis objek. Itu pendek.sumber
Jika Anda tahu pengecualian yang benar, maka Anda dapat menghubungi
misalnya:
dan buka "onProgressUpdate" dan lakukan yang berikut
Ini hanya akan membantu dalam beberapa kasus saja. Anda juga dapat menyimpan
Global
Exception
variabel dan mengakses pengecualian.sumber