Esperando que se complete un Runnable antes de ejecutar otro Runnable

Tengo una aplicación de Android con una actividad de pestaña principal y varias actividades dentro de las pestañas individuales. En onCreate () de mi actividad principal, tengo un runnable que crea una lista, y en las actividades individuales, hago uso de esta lista.

En el onCreate () de las actividades individuales, también tengo Runnables que operan en la lista. Sin embargo, necesito que estos Runnables se ejecuten sólo cuando Runnable de la actividad de la pestaña principal termine de crear la lista, de lo contrario tendría una lista nula. Estoy tratando de encontrar una manera elegante de hacer esto. En este momento, en Runnable de mi actividad principal, estoy configurando una variable booleana global isDone, y en Runnable de mi actividad individual, espero que isDone se establezca a través de un bucle while. Esto funciona, pero probablemente no es la mejor manera de hacerlo.

¿Alguna idea?

Gracias.

Edit: Estoy intentando el siguiente código, pero estoy recibiendo errores de tiempo de ejecución:

En el Runnable de mi MainActivity:

mainRunnable = new Runnable() { public void run() { try { generateList(); synchronized(this) { listDone = true; notifyAll(); } } catch (Exception e) { Log.e("BACKGROUND_PROC", e.getMessage()); } } }; Thread thread = new Thread(null, mainRunnable, "Background"); thread.start(); 

En Runnable de mi OtrosActividad:

 otherRunnable = new Runnable() { public void run() { synchronized(MainActivity.mainRunnable) { if (!MainActivity.getListDone()) { try { wait(); } catch (InterruptedException e) { } } } } }; Thread thread = new Thread(null, otherRunnable, "Background"); thread.start(); 

El mainRunnable parece ejecutarse completamente, pero el otherRunnable parece provocar que la aplicación se bloquee. Consigo el mensaje de error siguiente:

 01-10 15:41:25.543: E/WindowManager(7074): Activity com.myapp.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40539850 that was originally added here 01-10 15:41:25.543: E/WindowManager(7074): android.view.WindowLeaked: Activity com.myapp.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40539850 that was originally added here 

Puede utilizar los métodos wait y notify .

Para ello, debe haber algún objeto accesible a nivel mundial cuyo bloqueo no se utilice en ninguna otra parte del programa en este momento. Estoy asumiendo que la creación de lista Runnable sí mismo puede desempeñar este papel.

Así que puedes añadir algo como esto a la clase Runnable crea Runnable :

 private boolean listsDone = false; boolean getListsDone() { return listsDone; } 

Y algo así a su método run() , inmediatamente después de haber creado las listas:

 synchronized (this) { listsDone = true; notifyAll(); } 

Y algo así a los demás Runnable s ' run() métodos, en el punto donde tienen que esperar:

 synchronized (listCreatingRunnableObject) { if (!listCreatingRunnableObject.getListsDone()) { try { listCreatingRunnableObject.wait(); } catch (InterruptedException e) { // handle it somehow } } } 

Actualización: Para aclarar, ambos bloques synchronized necesitan ser sincronizados sobre el mismo objeto, y usted tiene que llamar wait() y notifyAll() en ese objeto. Si el objeto es Runnable , puede estar implícito para el primero (como en el código anterior), pero si es la actividad, debe utilizar explícitamente el objeto de actividad en ambos casos.

Bah. Estas respuestas son demasiado complicadas. Utilice una cola como esta:

 public class RunQueue implemements Runnable { private List list = new ArrayList(); public void queue(Runnable task) { list.add(task); } public void run() { while(list.size() > 0) { Runnable task = list.get(0); list.remove(0); task.run(); } } } 

Esto le permite usar un hilo en lugar de varios hilos. Además, puede mantener todos los objetos "Runnable" existentes al mismo tiempo que limpia cualquier código que tenga para las esperas y las combinaciones.

Configure un CountDownLatch con un valor de 1 en el hilo principal, y luego haga que los subprocesos dependientes lo esperen. Cuando el hilo principal está hecho, contando hacia abajo el pestillo a 0 y los camareros comenzará a la derecha hacia arriba.

Una espera activa utilizando un bucle while no es una buena idea en absoluto. Lo más simple sería que el primer Runnable acabara de encender el resto de ellos como su último paso. Si eso no se puede hacer que funcione por alguna razón, eche un vistazo a la publicación de un mensaje a un manejador.

¿Hay alguna razón por la que está utilizando Runnable s y no Thread s? Si utiliza Thread s, puede utilizar las diversas primitivas de comunicación de subprocesos que existen por este motivo exacto ( wait() y join() en particular).

He creado un método auxiliar que contiene todo el código para publicar un runnable y esperar hasta que termine de ejecutarse.

La lógica es similar a lo que @Taymon describe, pero la implementación es más general.

Compruébelo: https://gist.github.com/Petrakeas/ce745536d8cbae0f0761

  • Gradle: ¿Cómo puedo incluir un jar local de un proyecto de java dependiente en una compilación de Android?
  • Cómo utilizar Google Api de traducción en mi aplicación de Android
  • Android.util.Pair mantiene String como parámetros en androidTest pero nulo en (unidad) prueba
  • Android Consumer IR Manager Debe ser uno de:
  • La página de vista web de Android no carga correctamente la página
  • Usando strings.xml con Android
  • IllegalStateException en MediaPlayer
  • Entero aleatorio: Android
  • EOFException al leer la cinta QueueFile
  • Apache Commons IO en Android
  • Cómo limpiar RxJava fuego y olvidar suscripciones?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.