Как проверить, закончили ли все AsyncTasks?
у меня 3 AsyncTasks
и 1 ProgressBar
. Я хочу, когда любая из задач выполняется, индикатор выполнения виден, и когда все они заканчиваются, индикатор выполнения невидим.
в Java есть ExecutorService::isTerminated
чтобы проверить, все ли runnables закончены, но Android нет.
Update: 3 задачи выполняются одновременно.
рис.
9 ответов
хорошая графика. Но я боюсь, что для этого нет встроенного механизма. Вам придется реализовать его самостоятельно. Есть несколько решений, которые вы могли бы использовать -
- сохранить ссылку на все 3 задачи. Когда задача завершится, проверьте, завершены ли две другие задачи, если да, то закройте диалоговое окно выполнения, если нет, дождитесь завершения другой задачи и проверьте еще раз. Убедитесь, что вы освободите ссылки, когда закончите.
- Если вы не хотите держать эталонный магазин a счетчик. Когда задача завершится, увеличьте счетчик и проверьте, равен ли он 3. Если все задачи выполнены и вы закончили. Если вы реализуете это, убедитесь, что синхронизирован доступ к счетчику.
попробуйте использовать AsyncTask.getStatus (). Это прекрасно работает. См. ниже пример кода.
List<AsyncTask<String, String, String>> asyncTasks = new ArrayList<AsyncTask<String, String, String>>();
AsyncTask<String, String, String> asyncTask1 = new uploadTask().execute(string);
AsyncTask<String, String, String> asyncTask2 = new downloadTask().execute(string);
AsyncTask<String, String, String> asyncTask3 = new createTask().execute(string);
asyncTasks.add(asyncTask1);
asyncTasks.add(asyncTask2);
asyncTasks.add(asyncTask3);
вы можете позже зациклить AsyncTaskList и найти состояние каждой из задач, как показано ниже.
for(int i=0;i<asyncTasks.size();i++){
AsyncTask<String, String, String> asyncTaskItem = (AsyncTask<String, String, String>)asyncTasks.get(i);
// getStatus() would return PENDING,RUNNING,FINISHED statuses
String status = asyncTaskItem.getStatus().toString();
//if status is FINISHED for all the 3 async tasks, hide the progressbar
}
простым обходным путем было бы использование трех булевых переменных по одной для каждой AsyncTask, а затем проверить их соответствующим образом.
лучшим подходом было бы создать отдельный класс, который расширяет AsynTask и определяет интерфейс обратного вызова, который запускается в onPostExecute.
создать поле для хранения всех задач:
private ArrayList<HtmlDownloaderTask> mTasks;
запустить свои задачи таким образом:
HtmlDownloaderTask = new HtmlDownloaderTask(page.getHtml());
task.execute(page.getUrl());
//if you want parallel execution try this:
//task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,page.getUrl());
mTasks.add(task);
на onPostExecute MyAsyncTask:
int unfinishedTasks = 0;
for (HtmlDownloaderTask myDT : mTasks){
if(!(myDT.getStatus() == AsyncTask.Status.FINISHED)){
unfinishedTasks++;
}
}
if (unfinishedTasks == 1){
//We are all done. 1 Because its the current one that hasnt finished post execute
callWhateverMethod();
}
Ну как вы знаете, когда AsyncTask
заканчивается (когда onPostExecute
вызывается):
одним из решений может быть создание метода setProgressBarVisible()
который сохраняет счетчик и при первом вызове устанавливает видимый, и метод setProgressBarInvisible()
это уменьшает счетчик и когда ноль устанавливает индикатор выполнения невидимым.
:-? я думаю, это просто трюк. вы вернете сообщение в onPostExecute
каждого Asyntask
и сравнить его. (это сообщение может содержать время, например)
официальная поддержка CompletableFuture был введен с уровня API 24.
Он также доступен в Java 8 здесь.
можно использовать просто использовать что-то вроде:
taskA.thenCombine(taskB).thenCombine(taskC)
Я бы просто уведомил его в onPostExecute()
см. onPostExecute и 4 шага в документе для деталей и вы можете использовать EventBus
делать некоторые вещи.
попробуйте это, возможно, может помочь вам...
final ImageUploader _upload = new ImageUploader();
_upload.setValue(getApplicationContext(), _imagepath, _urlPHP);
_upload.execute();
Runnable _run;
Handler _h2;
_run = new Runnable() {
public void run() {
_h2 = new Handler();
_h2.postDelayed(this, 1000);
Toast.makeText(getApplicationContext(), "not finished", Toast.LENGTH_LONG).show();
if (_upload.getStatus() == AsyncTask.Status.FINISHED) {
Toast.makeText(getApplicationContext(), "finished", Toast.LENGTH_LONG).show();
_h2.removeCallbacks(_run);
}
}
};
_h2 = new Handler();
_h2.postDelayed(_run, 1);