gpt4 book ai didi

android - 如何在 Android 上进行非阻塞事件处理?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:24 27 4
gpt4 key购买 nike

这个问题是关于 Android 上的事件处理。它不特定于 c++。

我需要处理 UI/OS 事件,在处理完所有事件后不阻塞。

原因是我正在移植的应用程序非常大,不能轻易重写以在工作线程上处理它自己的东西。相反,应用程序引擎要求在冗长的操作期间处理 UI/OS 事件,否则会阻塞。

我发现 ALooper_pollAll(...) 不会为我做这个。例如,如果我在我的 Activity 中创建一个对话框并开始一个长时间的操作,ALooper_pollAll() 不会让我的对话框出现 - 它只会在我返回主循环时显示(我在 onNativeWindowCreated 中测试过)。

我发现几乎可行的唯一解决方案是通过 JNI 调用以下代码在 UI 线程上执行内部循环:

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;
}
}
}

不过,我还是想知道有没有更好的解决办法。

最佳答案

不确定我是否正确理解了问题,但您是否尝试过使用 IntentService?

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

来自文档:

This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics."

关于android - 如何在 Android 上进行非阻塞事件处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4994263/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com