有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在Android中从本机C/C++调用JavaAPI

Android C/C++本机调用Java API的例子很多。然而,我读过的所有这些示例都是安卓javaapi首先调用native,然后native使用传递的JNI-ENV调用其他javaapi

如果没有传递的JNI-ENV,C/C++如何获得它? C/C++本机是否可能通过创建JavaVM在Android中调用JavaAPI?如果是,请分享链接。 我已经通过了一个项目CoCos2dx,我无法找到明确的细节。 github。com/nokia developer/cocos2d-x-qt/tree/master/

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    我是这样做的。我通过引用盛亮的The Java Native Interface找到了答案;见第96页。我有一个名为ThreadEnv的类,它拥有当前线程的JNIEnv指针,并在第一次需要时创建它:

    class ThreadEnv
        {
        public:
        JNIEnv* GetEnv()
            {
            if (m_env == nullptr)
    #if defined(ANDROID) || defined(__ANDROID__)
                TheJvm->AttachCurrentThread(&m_env,nullptr);
    #else
                TheJvm->AttachCurrentThread((void**)&m_env,nullptr);
    #endif
            return m_env;
            }
        ~ThreadEnv()
            {
            if (m_env)
                TheJvm->DetachCurrentThread();
            }
    
        private:
        JNIEnv* m_env = nullptr;
        };
    

    然后我使用ththEnv对象,它是任何一个C++类的成员,它需要在我的JNI代码中调用GetEnv,以获得JNIENV指针。下面是一个如何在我的一个类中使用它的示例:看看OnChange成员函数

    class MyFrameworkObserver: public MFrameworkObserver, public MUserData
        {
        public:
        MyFrameworkObserver(jobject aFrameworkObject): m_framework_object(aFrameworkObject) { }
        ~MyFrameworkObserver()
            {
            JNIEnv* env = m_thread_env.GetEnv();
            if (env)
                env->DeleteGlobalRef(m_framework_object);
            }
    
        private:
        void OnViewChange() override { OnChange(TheFrameworkOnViewChangeMethodId); }
        void OnMainDataChange() override { OnChange(TheFrameworkOnMainDataChangeMethodId); }
        void OnDynamicDataChange() override { OnChange(TheFrameworkOnDynamicDataChangeMethodId); }
    
        void OnChange(jmethodID aMethodID)
            {
            JNIEnv* env = m_thread_env.GetEnv();
            if (env)
                env->CallVoidMethod(m_framework_object,aMethodID);
            }
    
        jobject m_framework_object;
        ThreadEnv m_thread_env;
        };