【问题标题】:jni: calling a java method in its appartment threadjni:在其appartment线程中调用一个java方法
【发布时间】:2015-08-29 09:26:18
【问题描述】:

我对 jni 还很陌生。

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

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

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

那么,我可以使用哪些选项?是否有用于在指定线程中发布 java 方法执行的 jni 方法?或者也许是相当于PostThreadMessage的Linux?我也可以在 java 代码中考虑解决方法,但更喜欢在本机端解决这个问题。

提前致谢。

【问题讨论】:

  • 发送MessageHandler,然后让handleMessage 调用回调怎么样?如果在构造 Handler 时未指定 Looper,则 Handler 应与应用程序的主线程 Looper 关联。
  • @Michael - 听起来很合理,问题是我也是 android/java 的初学者。我听说过MessageHandler,但不知道如何处理。一定会检查这个,谢谢。

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


【解决方案1】:

请参阅最近的相关讨论: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() 的近似版本(没有wParamlParam)可以像

MyHandler::sendEmptyMessage(int what) {
    write(messagePipe[1], &what, sizeof(what));
}

【讨论】:

    猜你喜欢
    • 2012-02-26
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多