Этот вопрос касается обработки событий на Android. Это не относится к c ++.
Мне нужно обрабатывать события UI / OS, без блокировки, когда все события были обработаны.
Причина в том, что приложение, которое я портирую, очень большое, и его нелегко переписать, чтобы оно работало с собственным материалом в рабочем потоке. Вместо этого ядро приложения запрашивает события UI / OS для обработки во время многоплановых операций, которые в противном случае блокировали бы.
Я обнаружил, что ALooper_pollAll (...) не делает этого для меня. Если я, например, создаю диалог в своей деятельности и запускаю длинную операцию, ALooper_pollAll () не заставит мой диалог появиться - он будет отображаться только когда я вернусь в основной цикл (я проверял это в onNativeWindowCreated).
Единственное решение, которое я нашел почти работающим, - это выполнить внутренний цикл в потоке пользовательского интерфейса, вызвав следующий код через 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
}
}
}
}
Это, однако, не оптимальное решение, потому что оно не будет зациклено, пока не будет больше событий для обработки (потому что события могут быть созданы во время выполнения цикла).
Во время моего исследования я обнаружил, что могу получить MessageQueue от Looper и добавить IdleHandler, который может выйти из моего внутреннего цикла. Я еще не пробовал, должен быть лучший способ.
Учитывая тот факт, что я должен придерживаться этой архитектуры, что является лучшим решением?
Обновление:
Используя MessageQueue, я могу достичь того, что мне нужно:
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;
}
}
}
Однако я все еще хотел бы знать, есть ли лучшее решение.