jni:在其appartment线程

时间:2015-08-29 09:26:19

标签: android c++ multithreading java-native-interface

我对jni很新。

我需要从java代码调用本机方法,这应该异步执行一个耗时的操作(在另一个线程中),最后它应该调用java回调。但是我需要在发起操作的同一个java线程中调用此回调。也就是说,java应用程序应该是单线程的,并且应该在该线程的上下文中调用所有回调。

我已经阅读了关于回调调用的教程,关于将全局引用保存到对象,获取适当的methodid并调用它的内容。 我也找到了关于如何从另一个线程(AttachCurrentThread)调用java方法的东西,但这不是我需要的。我需要在原始线程中进行java调用,所以问题是如何切换到该线程?

例如,在Win32中,我使用PostMessage / PostThreadMessage之类的东西来调用指定线程中的代码,假设它运行消息循环。还有像QueueUserAPC这样的替代方案,如果线程等待处于可警告状态的事件,则适用。

那么,我有哪些选择呢?是否有一个jni方法在指定的线程中发布java方法的执行?或者可能是等价于PostThreadMessage的Linux?我也可以考虑java代码中的变通方法,但更喜欢在本机方面解决这个问题。

提前致谢。

1 个答案:

答案 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));
}