Вы также можете просто уменьшаете счетчик в общем объекте как часть onPostExecute
. Поскольку onPostExecute
работает в одном потоке (основной поток), вам не придется беспокоиться о синхронизации.
UPDATE 1
Общий объект может выглядеть примерно так:
public class WorkCounter {
private int runningTasks;
private final Context ctx;
public WorkCounter(int numberOfTasks, Context ctx) {
this.runningTasks = numberOfTasks;
this.ctx = ctx;
}
// Only call this in onPostExecute! (or add synchronized to method declaration)
public void taskFinished() {
if (--runningTasks == 0) {
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx);
mgr.sendBroadcast(new Intent("all_tasks_have_finished"));
}
}
}
UPDATE 2
Согласно комментариям к этому ответу, OP ищет решение в котором он может избежать строительства нового класса. Это может быть сделано путем разделяя AtomicInteger
среди порождены AsyncTask
с:
// TODO Update type params according to your needs.
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
// This instance should be created before creating your async tasks.
// Its start count should be equal to the number of async tasks that you will spawn.
// It is important that the same AtomicInteger is supplied to all the spawned async tasks such that they share the same work counter.
private final AtomicInteger workCounter;
public MyAsyncTask(AtomicInteger workCounter) {
this.workCounter = workCounter;
}
// TODO implement doInBackground
@Override
public void onPostExecute(Void result) {
// Job is done, decrement the work counter.
int tasksLeft = this.workCounter.decrementAndGet();
// If the count has reached zero, all async tasks have finished.
if (tasksLeft == 0) {
// Make activity aware by sending a broadcast.
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx);
mgr.sendBroadcast(new Intent("all_tasks_have_finished"));
}
}
}
Если вы хотите ждать, то я предпочел бы использовать тему, как вы можете просто присоединиться нить. Весь смысл использования Async состоит в том, что он выполняется параллельно. Конечно, вы можете дождаться результата, используя Future for Async. –
У вас есть контроль над 'AsyncTask' и знаете ли вы количество задач заранее? если это так, вы можете просто отсчитывать (целочисленная переменная, без необходимости причудливой синхронизации) количество готовых задач в 'onPostExecute()' и действовать, когда счетчик достигает нуля. – dhke
@dhke в этом случае вам нужно запустить цикл простоя, и мне это не очень нравится –