This question is about event handling on Android. This does not apply to C ++.
I need to handle UI / OS events, without blocking, when all events have been processed.
The reason is that the application that I am porting is very large and cannot be easily rewritten to work with its own material in the workflow. Instead, the application engine requests that UI / OS events be processed during long operations that would otherwise be blocked.
I found that ALooper_pollAll (...) does not do this for me. If, for example, I create a dialogue in my activity and start a long operation, ALooper_pollAll () will not display my dialogue - it will be displayed only when I return to the main loop (I tested this in onNativeWindowCreated).
The only solution I found almost to work was to make an inner loop in the user interface thread by calling the following code via 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);
This, however, is not an optimal solution because it will not loop until there are more events to process (since events can be created during the loop).
During my research, I found that I could get a MessageQueue from Looper and add an IdleHandler that could exit my inner loop. I have not tried this yet, there must be a better way.
Given the fact that this is the architecture I have to stick with, is the best solution?
Update:
Using MessageQueue I can achieve what I need:
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) {
However, I would still like to know if there is a better solution.
android events jni looper message-queue
Ludvig A. Norin Feb 14 '11 at 15:59 2011-02-14 15:59
source share