studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android events jni message-queue looper

programacion - ¿Cómo puedo hacer el procesamiento de eventos sin bloqueo en Android?



manual de programacion android pdf (1)

Esta pregunta es sobre el manejo de eventos en Android. No es específico de c ++.

Necesito procesar eventos de UI / OS, sin bloquear cuando se hayan procesado todos los eventos.

La razón es que la aplicación que estoy portando es muy grande y no se puede reescribir fácilmente para tratar sus propias cosas en un hilo de trabajo. En su lugar, el motor de aplicaciones solicita que los eventos de UI / OS se procesen durante operaciones largas que de lo contrario estarían bloqueando.

He descubierto que ALooper_pollAll (...) no hace esto por mí. Si, por ejemplo, creo un cuadro de diálogo en mi actividad e inicio una operación larga, ALooper_pollAll () no hará que aparezca mi cuadro de diálogo; se mostrará solo cuando regrese al ciclo principal (lo probé en NativeWindowCreated).

La única solución que he encontrado para casi funcionar es hacer un bucle interno en el hilo de la interfaz de usuario, llamando al siguiente código a través de JNI:

public class MyActivity extends NativeActivity { private Handler _uiEventsHandler = null; private Runnable _uiEventsTask = new Runnable() { public void run() { Looper looper = Looper.myLooper(); looper.quit(); _uiEventsHandler.removeCallbacks(this); _uiEventsHandler = null; } }; public void ProcessEvents(int timeout) { if (_uiEventsHandler==null) { Looper looper = Looper.myLooper(); _uiEventsHandler = new Handler(looper); _uiEventsHandler.removeCallbacks(_uiEventsTask); //_uiEventsHandler.postDelayed(_uiEventsTask,timeout); _uiEventsHandler.post(_uiEventsTask); try { looper.loop(); } catch (RuntimeException re) { // We get an exception when we try to quit the loop, but the inner loop actually terminates } } } }

Sin embargo, esta no es una solución óptima, ya que no se repetirá hasta que no haya más eventos que procesar (porque los eventos pueden crearse durante la ejecución del ciclo).

Durante mi investigación, descubrí que puedo obtener el MessageQueue del Looper y agregar un IdleHandler que puede salir de mi bucle interno. Todavía no lo he intentado, tiene que haber una mejor manera.

Dado el hecho de que esta es la arquitectura que debo seguir, ¿cuál es la mejor solución?

Actualizar:

Usando MessageQueue puedo lograr lo que necesito:

public class MyActivity extends NativeActivity { private class IdleHandler implements MessageQueue.IdleHandler { private Looper _looper; protected IdleHandler(Looper looper) { _looper = looper; } public boolean queueIdle() { _uiEventsHandler = new Handler(_looper); _uiEventsHandler.post(_uiEventsTask); return(false); } }; private boolean _processingEventsf = false; private Handler _uiEventsHandler = null; private Runnable _uiEventsTask = new Runnable() { public void run() { Looper looper = Looper.myLooper(); looper.quit(); _uiEventsHandler.removeCallbacks(this); _uiEventsHandler = null; } }; public void ProcessEvents() { if (!_processingEventsf) { Looper looper = Looper.myLooper(); looper.myQueue().addIdleHandler(new IdleHandler(looper)); _processingEventsf = true; try { looper.loop(); } catch (RuntimeException re) { // We get an exception when we try to quit the loop. } _processingEventsf = false; } } }

Sin embargo, todavía me gustaría saber si hay una mejor solución.


No estoy seguro de haber entendido la pregunta correctamente, pero ¿ha intentado utilizar un servicio de intendencia?

http://developer.android.com/reference/android/app/IntentService.html

De los documentos:

Este patrón de "procesador de cola de trabajo" se usa comúnmente para descargar tareas del hilo principal de una aplicación. La clase IntentService existe para simplificar este patrón y cuidar la mecánica ".