Java调用NDK插件,该插件使用侦听器调用自己的Java 我有一个C++ NDK插件(.so),我想修改Android上的一个活动布局。该插件需要支持推送通知和侦听器接口

Java调用NDK插件,该插件使用侦听器调用自己的Java 我有一个C++ NDK插件(.so),我想修改Android上的一个活动布局。该插件需要支持推送通知和侦听器接口,java,android,c++,android-ndk,java-native-interface,Java,Android,C++,Android Ndk,Java Native Interface,为此,我知道我需要使用JNI接口来启动对Java的请求,并从UI元素接收事件。然而,我的问题是C++如何正确地访问JVM或JENV。 警告所有psudo代码。我的问题和困惑是内联的 public class MyActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new Tes

为此,我知道我需要使用JNI接口来启动对Java的请求,并从UI元素接收事件。然而,我的问题是C++如何正确地访问JVM或JENV。 警告所有psudo代码。我的问题和困惑是内联的

public class MyActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new TestRenderer().Start()
    }
}

class TestRenderer {
    // Messages to the plugin.
    void native Start();

    // Messages from the plugin.
    void OnCreated() {
        // Do something.
    }

    static {
        System.loadLibrary("testrenderer");
    }
}
然后它将调用JNI

JNIEXPORT void JNICALL Java_TestRenderer_Start(JNIEnv* env, jobject obj)
{
    // Create my C++ class that does all the work!
    TestRenderer renderer = new TestRenderer();
    renderer.Start();
}
<>但是,当我的C++ TestReNDERER调用它自己的java时,这里是我在这里做什么的空白。
class TestRenderer
{
public:
    ...
    void Start()
    {
        // Create a relative view.
        CreateRelativeView();
    }

private:
    void CreateRelativeView()
    {
        // JNI create my java class and find method.
        // Call method against against that Java class.
        // What JVM, JEnv, or jobject should I use?
        // AT THIS EXACT POINT I NEED ACCESS TO THE ACTIVITY CONTEXT.
        // new CustomView(context); <--- ?????
    }

    // Also, how do I ensure I call OnCreated on the right Java object.
    void OnCreated()
    {
        ...
        // Call method against Java TestRenderer on the right jobject.
    }
};
我知道这听起来有点复杂,但是如果我能够在中间层中通过NeXT,它就能解决其他平台上的许多共享代码问题。我觉得这是完全有可能的,但我还是画了个空白


提前感谢。

可以安全地缓存
JavaVM*
,因此您可以在
JNI_OnLoad
中获取接收到的一个,并将其保存在全局变量中。缓存
JNIEnv*
是不安全的,因此从任意线程获取有效的
JNIEnv*
需要一些工作。明白了,我明白了。因此,根据您所说的,听起来最好的方法是将活动存储在某种类型的单例值中,以从使用JNI_OnLoad缓存的JavaVM的GetEnv/AttachCurrentThread检索。这听起来也很理想,我希望缓存我创建的这个jobject,以维护从本机创建的生命周期CustomView。。。如何知道哪个CustomView对应于哪个TestRenderer?我的猜测是,我将为“public native OnCreated();”实现JNI,并且会有一些方法来比较作业对象吗?
public class CustomView extends RelativeLayout {
    public CustomView(Context context) {
        super(context);

        // Call back into native
        OnCreated();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Call back into native
        OnCreated();
    }

    // My listener call I would want invoked to go back through plugin to client.
    public native OnCreated();

    static {
        // I assume back to the same plugin?
        System.loadLibrary("testrenderer");
    }
}