Untaian AsyncTask tidak pernah mati

112

Saya menggunakan AsyncTasks untuk mengambil data sebagai respons terhadap pengguna yang menekan tombol. Ini berfungsi dengan baik dan menjaga antarmuka tetap responsif saat mengambil data, tetapi ketika saya memeriksa apa yang terjadi di debugger Eclipse, saya menemukan bahwa setiap kali yang baru AsyncTaskdibuat (yang cukup sering, karena mereka hanya dapat digunakan sekali ), utas baru sedang dibuat tetapi tidak pernah dihentikan.

Hasilnya adalah sejumlah besar AsyncTaskutas hanya duduk di sana. Saya tidak yakin apakah ini menjadi masalah dalam praktik atau tidak, tetapi saya benar-benar ingin menyingkirkan utas tambahan tersebut.

Bagaimana saya bisa membunuh utas ini?

Komputer
sumber
Apa yang Anda maksud dengan "tidak pernah dihentikan"? Apakah tugas tidak pernah mengakhiri metode doInbackground atau Anda hanya melihat objek asynctask di pelacak alokasi?
Francesco Laurita
7
The doInBackgroundMetode selesai, tapi thread terus muncul di jendela debug. Misalnya: Thread [<23> AsyncTask #4](Running)
Computerish

Jawaban:

202

AsyncTaskmengelola kumpulan utas, dibuat dengan ThreadPoolExecutor. Ini akan memiliki 5 hingga 128 utas. Jika ada lebih dari 5 utas, utas ekstra itu akan bertahan paling lama 10 detik sebelum dilepas. (catatan: angka-angka ini untuk kode sumber terbuka yang saat ini terlihat dan bervariasi menurut rilis Android).

AsyncTaskTolong tinggalkan utasnya.

CommonsWare
sumber
Terima kasih untuk penjelasannya! Saya senang mengetahui bahwa saya tidak melakukan kesalahan apa pun. Karena penasaran, kenapa didesain seperti itu? Mengapa tidak mengakhiri utas setelah semua metode kembali?
Computerish
7
Agaknya untuk menghemat waktu membagi utas pada permintaan nanti.
CommonsWare
@CommonsWare saya memiliki layanan di mana saya menjalankan AsyncTask untuk melakukan beberapa operasi dan layanan dimulai ketika tombol widget ditekan dan ketika tugas selesai harus segera menghentikan layanan, tetapi terkadang AsyncTask tidak akan mati, jadi bisakah Anda beri tahu saya bagaimana cara menghentikannya
Berburu
1
@SreekanthKarumanaghat: Menggunakan sebuah AsyncTaskuntuk sesuatu yang akan memakan waktu selama itu adalah ide yang buruk secara umum. Tapi tidak, komentar saya tentang utas tambahan akan hilang ketika tidak digunakan. Jadi, ketika salah satu dari 6 tugas Anda berakhir, utasnya akan tetap berada di kumpulan selama 10 detik, setelah itu utas itu akan dihentikan.
CommonsWare
1
@SreekanthKarumanaghat: "Pertanyaan saya adalah apakah ada batasan untuk menjalankan 20 (katakanlah) AsyncTasks secara Paralel?" - Memanfaatkan AsyncTaskhari ini secara signifikan bukanlah rencana yang bagus. Memiliki 20+ yang dapat berjalan selama 10+ detik adalah hal yang seharusnya gagal dalam tinjauan kode. Jika Anda membuat 20 tugas secara berurutan, hanya beberapa yang akan dijalankan sekaligus, dan sisanya akan diantrekan untuk dieksekusi nanti. Berapa banyak yang akan dijalankan sekaligus didasarkan pada jumlah inti CPU. AFAIK, algoritme saat ini adalah 2N + 1 utas paralel, di mana N adalah jumlah inti.
CommonsWare
24

Selain tanggapan CommonsWare:

Saat ini saya menggunakan Android 2.2, dan aplikasi saya tidak menggunakan lebih dari satu AsyncTask setiap saat, tetapi saya membuat yang baru setiap x menit. Awalnya Utas AsyncTask baru mulai muncul (Utas baru untuk AsyncTask baru) tetapi setelah 5 utas (seperti yang disebutkan oleh CommonsWare), utas tersebut tetap terlihat di jendela debug, dan digunakan kembali saat utas AsyncTask baru diperlukan. Mereka hanya tetap di sana sampai debugger terputus.

Tom de Waard
sumber
2
Ya, dikonfirmasi: Saya melihat tidak lebih dari 5 AsyncTasks.
Seraphim's
3

Gejala yang sama di sini. Dalam kasus saya, utas berkeliaran setelah saya mematikan Aktivitas, dan saya berharap Aplikasi ditutup sepenuhnya. Masalah sebagian diselesaikan dengan menggunakan eksekutor utas tunggal:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

Hal ini membuat utas menghilang setelah menyelesaikan pekerjaannya.

karnbo
sumber
Jawaban ini membuat AsyncTask menghilang setelah dijalankan, mungkin ini bukan "cara google melakukan sesuatu" tetapi menyelesaikan pekerjaan. Terima kasih.
Henrique de Sousa
Ini memecahkan masalah khusus saya tentang menjalankan Asynctasks pada satu utas.
Law Gimenez
0

Gunakan ThreadPoolExecutor .

BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

Posting Runnabletugas Anda dengan menggunakan metode execute () .

void execute (Runnable command)

Menjalankan tugas yang diberikan suatu saat nanti. Tugas dapat dijalankan di utas baru atau di utas gabungan yang ada

Mengenai kueri kedua Anda:

Bagaimana saya bisa membunuh utas ini?

Setelah Anda selesai dengan semua pekerjaan Anda ThreadPoolExecutor , matikan dengan benar seperti yang dikutip dalam posting di bawah ini:

Cara mematikan Java ExecutorService dengan benar

Ravindra babu
sumber