17

Tengo 3 AsyncTasks y 1 ProgressBar. Quiero cuando se ejecuta alguna de las tareas, la barra de progreso es visible y cuando todas terminan, la barra de progreso es invisible.¿Cómo verificar si terminaron todas las AsyncTasks?

En Java, hay ExecutorService :: isTerminated para verificar si todos los runables han terminado pero Android no.

Actualización: 3 tareas se ejecutan al mismo tiempo.

Figura. enter image description here

+0

Prueba la solución que he proporcionado a continuación, funciona como un encanto – Jagadeesh

Respuesta

21

Bonito gráfico. Pero me temo que no hay un mecanismo de construcción para esto. Tendrá que implementarlo usted mismo. Hay pocas soluciones que podría usar:

  1. Mantenga una referencia a las 3 tareas. Cuando la tarea finalice, compruebe si las otras dos tareas también están finalizadas, en caso afirmativo, cierre el cuadro de diálogo de progreso si no espera a que finalice otra tarea y vuelva a verificar. Asegúrese de liberar las referencias cuando haya terminado.
  2. Si no desea mantener un mostrador de referencia un contador. Cuando la tarea finalice, incremente el contador y verifique si es igual a 3. Si todas las tareas finalizaron y usted terminó. Si implementa esto, asegúrese de sincronizar el acceso al contador.
2

Una solución simple sería utilizar tres variables booleanas, una para cada AsyncTask y luego verificarlas en consecuencia.

Un mejor enfoque sería crear una clase separada que extienda AsynTask y defina una interfaz de devolución de llamada que se activa enPostExecute.

1

bien como lo hace saber cuándo termina una AsyncTask (cuando onPostExecute se llamaba): Una solución podría ser la creación de un setProgressBarVisible() método que mantiene un contador y en la primera llamada conjuntos visible, y una setProgressBarInvisible método() que disminuye el contador y cuando el cero establece la barra de progreso invisible.

0

: -? creo que es solo un truco devolverá algún mensaje al onPostExecute de cada Asyntask y lo comparará. (este mensaje puede contener una hora, por ejemplo)

6

Pruebe usar AsyncTask.getStatus(). Esto funciona perfectamente bien. Consulte a continuación código de ejemplo

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); 

más tarde puede rizar el AsyncTaskList y encontrar cada uno de los estados de las tareas de la siguiente manera.

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 
} 
+0

lo hice sin los nombres, pero funcionó a la perfección .. Gracias! Luego eliminé los elementos de ArrayList (cuando el estado == finalizó) en lugar de simplemente verificar el estado. Esto lo haría más fácil en conjuntos más grandes de asyncTasks como mi conjunto de más de 30 tareas. –

1

crear un campo para contener todas las tareas:

private ArrayList<HtmlDownloaderTask> mTasks; 

Iniciar las tareas de esta manera:

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); 

en el onPostExecute de 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(); 

} 
-1

probar esto , tal vez puede ayudarte ...

  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); 
0

Un apoyo oficial de CompletableFuture se introdujo desde el nivel de la API 24.

También está disponible en Java 8 here.

Se puede utilizar simplemente usar algo como:

taskA.thenCombine(taskB).thenCombine(taskC) 
Cuestiones relacionadas