我有一个使用这样的选择循环的网络应用程序:
bool shutdown=false;
while (!shutdown) {
[do something]
select(...,timeout);
}
由于应用程序需要接收Intent,需要处理GUI等,因此主循环在Android应用程序中不能像这样工作。
我认为我基本上有三种可能性:
第一种可能性并不容易,因为java没有选择适用于fds。简单地使用select和return之后每个循环到java都不是一个优雅的可能性,因为这需要将超时设置为20ms,以便在程序的java部分有一个很好的响应时间。
第二个概率听起来更好但我在java和程序的c ++ / c部分之间做了一些沟通。冷酷的事情:
我没有探究第三种可能性,但我认为这不是可行的方法。
我想我可以一起破解一些可行的东西,但我会问最佳选择路径是什么。
答案 0 :(得分:1)
根据提供的有限信息,我可以考虑以下方法:
循环可以在一个单独的线程中运行,有两个选项:
a)寻找gui led变更(基于全局本地状态变量的值,例如,en_type的native_app_state)
b)发生触发回调Java的事情
您可以使用单独的本机函数或一个集成的本机函数来响应来自Java的GUI事件 - 您可以在其中使用该全局本机状态变量的状态。
您可以根据每个州的情况以及应用程序的性能限制来优化实施。
答案 1 :(得分:1)
也许您可以将Java NIO用于本机应用程序的网络层。 java.nio.channels.Selector为您提供了与C的select()相当的Java。而java.nio.channels.Channel类似于C中的fd。
此示例代码不是Android特定的,但应该可以使用(或至少让您了解使用情况):http://www.exampledepot.com/egs/java.nio/NbClient.html
答案 2 :(得分:1)
关于IPC:Looper
- 或至少NDK实现ALooper
- 使用POSIX pipe()
作为IPC的手段;你可以在android_app_glue.c中看到一些这种情况,它是NDK的标准配置。作为该文件的参考,有问题的行是:
int msgpipe[2];
if (pipe(msgpipe)) {
LOGE("could not create pipe: %s", strerror(errno));
return NULL;
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
,关键行是
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, &android_app->cmdPollSource);
其中第二个参数(fd
)是文件描述符:
int ALooper_addFd ( ALooper * looper,
int fd,
int ident,
int events,
ALooper_callbackFunc callback,
void * data
)
...如果他们将它用于native_app_glue.c
,用于游戏等等,我认为它效率很高。