How can I handle non-blocking events on Android?

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); //_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 } } } } 

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) { // We get an exception when we try to quit the loop. } _processingEventsf = false; } } } 

However, I would still like to know if there is a better solution.

+5
android events jni looper message-queue
Feb 14 '11 at 15:59
source share
1 answer

Not sure if I understood the question correctly, but were you trying to use IntentService?

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

From the docs:

This work queue pattern is typically used to unload tasks from the main application thread. The IntentService class exists to simplify this pattern and take care of the mechanics. "

0
Apr 02 2018-12-12T00:
source share



All Articles