Saya menjalankan operasi pengambilan file audio dan pemutaran file audio jarak jauh di utas latar belakang menggunakan AsyncTask
. SEBUAHCancellable
progress bar ditampilkan untuk waktu pengambilan operasi berjalan.
Saya ingin membatalkan / membatalkan proses AsyncTask
ketika pengguna membatalkan (memutuskan) operasi. Bagaimana cara yang ideal untuk menangani kasus seperti itu?
android
android-asynctask
Samuh
sumber
sumber
while(running)
dengan yangwhile(!isCancelled())
orang lain katakan di sini di komentar.Jika Anda melakukan perhitungan :
isCancelled()
secara berkala.Jika Anda melakukan permintaan HTTP :
HttpGet
atauHttpPost
suatu tempat (mis. Bidang publik).cancel
, teleponrequest.abort()
. Ini akan menyebabkanIOException
terlempar ke dalam AndadoInBackground
.Dalam kasus saya, saya memiliki kelas konektor yang saya gunakan di berbagai AsyncTasks. Untuk membuatnya tetap sederhana, saya menambahkan
abortAllRequests
metode baru ke kelas itu dan memanggil metode ini langsung setelah memanggilcancel
.sumber
HttpGet.abort()
dari thread latar belakang atau Anda akan mendapatkan fileandroid.os.NetworkOnMainThreadException
.cancel(true)
menghentikan permintaan? Dari dokumentasi:If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
HttpURLConnection.disconnect();
cancel(true)
. Saya menggunakannya dan berhasil.Masalahnya adalah panggilan AsyncTask.cancel () hanya memanggil fungsi onCancel dalam tugas Anda. Di sinilah Anda ingin menangani permintaan pembatalan.
Berikut adalah tugas kecil yang saya gunakan untuk memicu metode pembaruan
sumber
running
panji sendiri . AsyncTask memiliki tanda internal yang disetel saat tugas telah dibatalkan. Gantiwhile (running)
denganwhile (!isCancelled())
. developer.android.com/reference/android/os/… Jadi dalam kasus sederhana ini, Anda tidak perluonCancelled()
menimpa.Sederhana: jangan gunakan file
AsyncTask
.AsyncTask
dirancang untuk pengoperasian singkat yang berakhir dengan cepat (puluhan detik) dan karenanya tidak perlu dibatalkan. "Pemutaran file audio" tidak memenuhi syarat. Anda bahkan tidak memerlukan utas latar belakang untuk pemutaran file audio biasa.sumber
onPostExecute()
untuk melihat apakah Anda harus melanjutkan pekerjaan.Satu-satunya cara untuk melakukannya adalah dengan memeriksa nilai metode isCancelled () dan menghentikan pemutaran saat mengembalikan nilai true.
sumber
Ini adalah bagaimana saya menulis AsyncTask saya
, titik kuncinya adalah menambahkan Thread.sleep (1);
sumber
Variabel kelas AsyncTask global kami
Dan tindakan KEYCODE_BACK yang mengganggu AsyncTask
Ini bekerja untuk saya.
sumber
Saya tidak suka memaksa interupsi tugas asinkron saya dengan
cancel(true)
tidak perlu karena mereka mungkin memiliki sumber daya untuk dibebaskan, seperti menutup soket atau aliran file, menulis data ke database lokal dll. Di sisi lain, saya telah menghadapi situasi di mana tugas async menolak untuk menyelesaikan sendiri sebagian waktu, misalnya kadang-kadang ketika aktivitas utama ditutup dan saya meminta tugas asinkron untuk diselesaikan dari dalam metode aktivitasonPause()
. Jadi, ini bukan hanya soal meneleponrunning = false
. Saya harus mencari solusi campuran: keduanya memanggilrunning = false
, lalu memberikan tugas asinkron beberapa milidetik untuk diselesaikan, dan kemudian memanggil salah satucancel(false)
ataucancel(true)
.Akibatnya, setelah
doInBackground()
selesai, terkadangonCancelled()
metode ini dipanggil, dan terkadangonPostExecute()
. Tapi setidaknya penghentian tugas asinkron dijamin.sumber
Dengan mengacu pada jawaban Yanchenko pada 29 April '10: Menggunakan pendekatan 'while (running)' adalah hal yang rapi ketika kode Anda di bawah 'doInBackground' harus dijalankan beberapa kali selama setiap eksekusi AsyncTask. Jika kode Anda di bawah 'doInBackground' harus dijalankan hanya sekali per eksekusi AsyncTask, menggabungkan semua kode Anda di bawah 'doInBackground' dalam loop 'while (running)' tidak akan menghentikan kode latar belakang (utas latar belakang) agar tidak berjalan ketika AsyncTask sendiri dibatalkan, karena kondisi 'while (running)' hanya akan dievaluasi setelah semua kode di dalam while loop telah dieksekusi setidaknya sekali. Karena itu, Anda harus (a.) Memecah kode Anda di bawah 'doInBackground' menjadi beberapa blok 'saat (menjalankan)' atau (b.) Melakukan banyak 'isCancelled'https://developer.android.com/reference/android/os/AsyncTask.html .
Untuk opsi (a.), Seseorang dapat mengubah jawaban Yanchenko sebagai berikut:
Untuk opsi (b.) Kode Anda di 'doInBackground' akan terlihat seperti ini:
sumber