Các lý do cho các trường hợp cháy và quên của ASyncTask được nêu chi tiết khá rõ trong câu trả lời của Steve Prentice - Tuy nhiên, trong khi bạn bị hạn chế số lần bạn thực thi ASyncTask, bạn có thể tự do làm những gì bạn thích trong khi luồng đang chạy .. .
Đặt mã thực thi của bạn bên trong một vòng lặp trong doInBackground () và sử dụng khóa đồng thời để kích hoạt mỗi lần thực thi. Bạn có thể truy xuất kết quả bằng cách sử dụng PublishProTHER () / onProTHERUpdate () .
Thí dụ:
class GetDataFromServerTask extends AsyncTask<Input, Result, Void> {
private final ReentrantLock lock = new ReentrantLock();
private final Condition tryAgain = lock.newCondition();
private volatile boolean finished = false;
@Override
protected Void doInBackground(Input... params) {
lock.lockInterruptibly();
do {
// This is the bulk of our task, request the data, and put in "result"
Result result = ....
// Return it to the activity thread using publishProgress()
publishProgress(result);
// At the end, we acquire a lock that will delay
// the next execution until runAgain() is called..
tryAgain.await();
} while(!finished);
lock.unlock();
}
@Override
protected void onProgressUpdate(Result... result)
{
// Treat this like onPostExecute(), do something with result
// This is an example...
if (result != whatWeWant && userWantsToTryAgain()) {
runAgain();
}
}
public void runAgain() {
// Call this to request data from the server again
tryAgain.signal();
}
public void terminateTask() {
// The task will only finish when we call this method
finished = true;
lock.unlock();
}
@Override
protected void onCancelled() {
// Make sure we clean up if the task is killed
terminateTask();
}
}
Tất nhiên, điều này phức tạp hơn một chút so với cách sử dụng ASyncTask truyền thống và bạn từ bỏ việc sử dụng PublishProTHER () để báo cáo tiến độ thực tế. Nhưng nếu bộ nhớ là mối quan tâm của bạn, thì phương pháp này sẽ đảm bảo chỉ còn một ASyncTask trong heap khi chạy.