Cómo esperar a que Android runOnUiThread para ser terminado?
Tengo un hilo de trabajo que crea un objeto runnable y llama a runOnUiThread en él, porque se ocupa de las vistas y de los controles. Me gustaría usar el resultado del trabajo del objeto ejecutable de inmediato. ¿Cómo espero que termine? No me molesta si está bloqueando.
- OnSaveInstanceState / onPause - espera hasta que el estado se salve por completo antes de permitir que se procese el proceso
- Bloques sincronizados android
- RxAndroid: cambios de interfaz de usuario en el subproceso Schedulers.io ()
- Android esperando el hilo de la interfaz de usuario
- Lo que se mata con el hilo de la interfaz de usuario de Android
- Conjunto de subprocesos en Java
- ¿Cómo evitar la espera en el hilo principal cuando se añaden los encabezados a las solicitudes de retrofit?
- Android, creando un hilo sencillo que actualizará mi contador de segundos
- ¿Algún consejo sobre cómo acelerar esto en Android?
- Android- Thread.join () hace que la aplicación se bloquee
- ¿Se asignan automáticamente nuevos subprocesos a un núcleo de CPU diferente en Java?
- Llamada Hilo principal de hilo secundario en Java / Android
- Comunicación multihilo: ¿qué tan bueno es el uso de variables atómicas como AtomicInteger? ¿Por qué no hay AtomicFloat?
Sólo rascar los puntos destacados
synchronized( myRunnable ) { activity.runOnUiThread(myRunnable) ; myRunnable.wait() ; // unlocks myRunable while waiting }
Mientras tanto … en myRunnable …
void run() { // do stuff synchronized(this) { this.notify(); } }
Andrew respuesta es buena, creo una clase para un uso más fácil.
Implementación de interfaces:
/** * Events for blocking runnable executing on UI thread * * @author * */ public interface BlockingOnUIRunnableListener { /** * Code to execute on UI thread */ public void onRunOnUIThread(); }
Implementación de clase:
/** * Blocking Runnable executing on UI thread * * @author * */ public class BlockingOnUIRunnable { // Activity private Activity activity; // Event Listener private BlockingOnUIRunnableListener listener; // UI runnable private Runnable uiRunnable; /** * Class initialization * @param activity Activity * @param listener Event listener */ public BlockingOnUIRunnable( Activity activity, BlockingOnUIRunnableListener listener ) { this.activity = activity; this.listener = listener; uiRunnable = new Runnable() { public void run() { // Execute custom code if ( BlockingOnUIRunnable.this.listener != null ) BlockingOnUIRunnable.this.listener.onRunOnUIThread(); synchronized ( this ) { this.notify(); } } }; } /** * Start runnable on UI thread and wait until finished */ public void startOnUiAndWait() { synchronized ( uiRunnable ) { // Execute code on UI thread activity.runOnUiThread( uiRunnable ); // Wait until runnable finished try { uiRunnable.wait(); } catch ( InterruptedException e ) { e.printStackTrace(); } } } }
Usándolo:
// Execute an action from non-gui thread BlockingOnUIRunnable actionRunnable = new BlockingOnUIRunnable( yourActivity, new BlockingOnUIRunnableListener() { public void onRunOnUIThread() { // Execute your activity code here } } ); actionRunnable.startOnUiAndWait();
Tal vez un poco simplista, pero un mutex hará el trabajo:
final Semaphore mutex = new Semaphore(0); activity.runOnUiThread(new Runnable() { @Override public void run() { // YOUR CODE HERE mutex.release(); } }); try { mutex.acquire(); } catch (InterruptedException e) { e.printStackTrace(); }
Una solución podría ser aprovechar el FutureTask<T>
Java, que tiene el beneficio de que alguien más ya ha tratado todos los posibles problemas de concurrencia para usted:
public void sample(Activity activity) throws ExecutionException, InterruptedException { Callable<Void> callable = new Callable<Void>() { @Override public Void call() throws Exception { // Your task here return null; } }; FutureTask<Void> task = new FutureTask<>(callable); activity.runOnUiThread(task); task.get(); // Blocks }
Incluso puede devolver un resultado del hilo principal reemplazando Void
por otra cosa.
Creo que la forma más sencilla de lograr esto es usando un "CountDownLatch".
final CountDownLatch latch = new CountDownLatch(1); runOnUiThread(new Runnable() { @Override public void run() { // Do something on the UI thread latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } // Now do something on the original thread
(Creo que esta pregunta es un duplicado de " Cómo hacer que la tarea del temporizador se espere hasta que runOnUiThread se complete ")
Utilice la clase AsyncTask, sus métodos onPostExecure y onProgressUpdate se ejecutan mediante el subproceso MAIN (el subproceso de UI).
http://developer.android.com/reference/android/os/AsyncTask.html
Es la mejor manera para su caso!
Espero que esto le pueda ayudar.
- Ciclo de vida de la actividad – recibir notificación de que el diseño está completo
- Cómo puedo formatear un número de cadena para tener comas en android Editar campo