如何在Android中从本地C/C++调用Java API

5
有很多例子可以展示Android C/C++本地调用Java API。然而,我读过的所有这些例子都是Android Java API首先调用本地API,然后本地API使用传递的JNI-ENV调用其他Java API。
没有传递的JNI-ENV,C/C++如何获得它呢?是否可能通过创建JavaVM在Android中使C/C++本地调用Java API?如果是,请分享链接。我已经查看了一个名为CoCos2dx的项目,但无法找到清晰的细节。
提前感谢!
1个回答

2
这是我做的方法。我是通过参考Sheng Liang的《Java本地接口》第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;
    };

我在JNI代码中将ThreadEnv对象作为任何需要它的C++类的成员,并调用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;
    };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接