我对jni很新。
我需要从java代码调用本机方法,这应该异步执行一个耗时的操作(在另一个线程中),最后它应该调用java回调。但是我需要在发起操作的同一个java线程中调用此回调。也就是说,java应用程序应该是单线程的,并且应该在该线程的上下文中调用所有回调。
我已经阅读了关于回调调用的教程,关于将全局引用保存到对象,获取适当的methodid并调用它的内容。
我也找到了关于如何从另一个线程(AttachCurrentThread
)调用java方法的东西,但这不是我需要的。我需要在原始线程中进行java调用,所以问题是如何切换到该线程?
例如,在Win32中,我使用PostMessage
/ PostThreadMessage
之类的东西来调用指定线程中的代码,假设它运行消息循环。还有像QueueUserAPC
这样的替代方案,如果线程等待处于可警告状态的事件,则适用。
那么,我有哪些选择呢?是否有一个jni方法在指定的线程中发布java方法的执行?或者可能是等价于PostThreadMessage
的Linux?我也可以考虑java代码中的变通方法,但更喜欢在本机方面解决这个问题。
提前致谢。
答案 0 :(得分:0)
请参阅最近的相关讨论: How do I post code to be run on the Android main thread from a separate thread in C++? 。最有趣的部分是2012年的this thread in android-ndk group。
TL; NR:来自JNI_OnLoad()
或其他早期发生的调用,来自UI线程,您调用
pipe2(messagePipe, O_NONBLOCK | O_CLOEXEC);
ALooper_addFd(ALooper_forThread(), messagePipe[0], 0, ALOOPER_EVENT_INPUT, handler, data);
在其他地方定义一个简单的处理函数:
int handler(int fd, int, void* pHandler) {
int what = 0;
read(fd, &what, sizeof(what));
static_cast<MyHandler *>(pHandler)->handle(what));
return 1;
}
现在,Handler.sendEmptyMessage()
的原生版本与CWinThread::PostThreadMessage()
(不包含 wParam 和 lParam )的近似模拟可以如此简单如
MyHandler::sendEmptyMessage(int what) {
write(messagePipe[1], &what, sizeof(what));
}