【问题标题】:How to start a new thread from JNI如何从 JNI 启动一个新线程
【发布时间】:2014-07-15 09:03:09
【问题描述】:

我需要从 android 应用程序的本机部分启动一个新线程。它必须在 JNI 中声明和定义。有人知道我该怎么做吗?如果有人会发布示例,我会非常高兴。

【问题讨论】:

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


    【解决方案1】:

    最简单的方法是使用 C++11 线程类。请参阅this topic,了解如何使用 Android NDK 启用 C++11。如果您在让线程类工作时遇到问题,另请参阅this post。然后你可以这样使用它:

    #include <thread>         // std::thread
             
    void foo() 
    {
       // do stuff...
    }
            
    void bar(int x)
    {
       // do stuff...
    }
            
    JNIEXPORT void JNICALL 
    Java_org_testjni_android_Game_someFunction(JNIEnv * env, jobject  obj)
    {
       std::thread first (foo);     // spawn new thread that calls foo()
       std::thread second (bar,0);  // spawn new thread that calls bar(0)
            
        //main, foo and bar now execute concurrently
            
        // synchronize threads:
       first.join();                // pauses until first finishes
       second.join();               // pauses until second finishes
            
    }
    

    如果你不能使用 C++11,就使用 pthread(POSIX 线程),它并没有太大的不同,除了它像旧的 C:

    #include <pthread.h>
        
        //This function will be called from a thread
        
    void *call_from_thread(void *) {
        //do stuff
        return NULL;
    }
        
    JNIEXPORT void JNICALL 
    Java_org_testjni_android_Game_someFunction(JNIEnv * env, jobject  obj)
    {
            pthread_t t;
        
            //Launch a thread
            pthread_create(&t, NULL, call_from_thread, NULL);
        
            //Join the thread with the main thread
            pthread_join(t, NULL);
     }
    

    这里有一些关于在 Android 中使用 POSIX 线程的more info

    此外,如果您想在除调用 JNI 函数的线程之外的任何线程中使用 JNIEnv 指针,您还需要查看如何将它绑定到当前线程。来自 JNI 规范:

    创建虚拟机

    JNI_CreateJavaVM() 函数加载并初始化 Java VM 并 返回一个指向 JNI 接口指针的指针。调用的线程 JNI_CreateJavaVM() 被认为是主线程。

    附加到虚拟机

    JNI接口指针(JNIEnv)只在当前有效 线。如果另一个线程需要访问 Java VM,它必须 首先调用 AttachCurrentThread() 将自身附加到 VM 并获取 一个 JNI 接口指针。连接到 VM 后,本机线程 就像在本机内部运行的普通 Java 线程一样工作 方法。本机线程一直连接到 VM,直到它调用 DetachCurrentThread() 分离自身。

    附加的线程应该有足够的堆栈空间来执行 合理的工作量。每个线程的堆栈空间分配是 操作系统特定的。例如,使用 pthreads,堆栈大小 可以在 pthread_create 的 pthread_attr_t 参数中指定。

    从虚拟机分离

    附加到 VM 的本机线程必须调用 DetachCurrentThread() 以 在退出之前分离自身。如果存在,线程不能自行分离 是调用堆栈上的 Java 方法。

    【讨论】:

    • 是否推荐使用 C++11 线程而不是 Boost 线程?或者他们是一样的。
    • 他们不一样,我相信Boost有更多的功能。提升您可以中断的线程,如 Java 或 .NET。这是比较:stackoverflow.com/questions/7241993/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 2012-05-06
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    相关资源
    最近更新 更多