此问题与Android上的事件处理有关。它不是特定于c ++。
我需要处理UI / OS事件,而不是在处理完所有事件时阻塞。
原因是我移植的应用程序非常大,无法轻易地重写以处理工作线程上的自己的东西。相反,应用程序引擎要求在冗长的操作期间处理UI / OS事件,否则这些操作将被阻止。
我发现ALooper_pollAll(...)不会为我这样做。例如,如果我在我的活动中创建一个对话框并开始一个长操作,ALooper_pollAll()将不会显示我的对话框 - 它只会在我返回主循环时显示(我在onNativeWindowCreated中对此进行了测试)。
我发现几乎可以解决的唯一解决方案是在UI线程上执行内部循环,通过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
}
}
}
}
然而,这不是最佳解决方案,因为它不会循环,直到没有更多事件要处理(因为事件可能在循环运行期间创建)。
在我的研究中,我发现我可以从Looper获取MessageQueue并添加一个可以退出内循环的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;
}
}
}
但是,我仍然想知道是否有更好的解决方案。
答案 0 :(得分:0)
我不确定我是否正确理解了这个问题,但您是否尝试过使用IntentService?
http://developer.android.com/reference/android/app/IntentService.html
来自文档:
此“工作队列处理器”模式通常用于从应用程序的主线程卸载任务。 IntentService类的存在是为了简化这种模式并处理机制。“