java - 使用C++获取Java对象调用Java方法

标签 java android c++ c native

我正在为 Android 使用 native 代码和 Java 代码进行开发。

我计划调用基于 C/C++ 代码的 Java 监听器。这个想法是 C/C++ 代码调用一个实际调用 Java Listener 的方法。

C/C++代码如下。我可以使用下面的代码调用 Java 方法:第一个代码块是在 JNI_OnLoad 中启动方法 ID 和类

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    jclass dataClass = env->FindClass("com/example/crowdlogic/NativeManager");
    dataClassHandle = (jclass)env->NewGlobalRef(dataClass);
    if (dataClassHandle == NULL) LOGI("dataClassHandle null");
    LOGI("init dataUpdateHandle");
    dataUpdateHandle = env->GetMethodID(dataClassHandle, "dataUpdate", "(I)V");
    if (dataUpdateHandle == NULL) LOGI("dataUpdateHandle null");

    return JNI_VERSION_1_6;
}

下一个代码块实际上是在调用它:

void sendCount(int totalCount) {
    jint jtotalCount = totalCount;
    jobject dataObjectHandle = env->NewObject(dataClassHandle, dataUpdateHandle);
    if (dataObjectHandle == NULL) LOGI("dataObjectHandle null");
    env->CallVoidMethod(dataObjectHandle, dataUpdateHandle, jtotalCount);
}

在Java部分,实际上是调用了dataUpdate方法,但没有调用监听器。监听器为空。这是 Java 监听器类

public class NativeManager {

    private static final String TAG = "crowdlogic:native_manager";

    // all the listener stuff below
    public interface Listener {
        public void onDataUpdated(int totalCount);
    }

    private Listener mListener = null;

    public void registerListener (Listener listener) {
        mListener = listener;
    }

    public void dataUpdate(int totalCount) { // call this from JNI in C++ class
        // now notify if someone is interested.
        Log.i(TAG, "Data update in Java called");
        if (mListener != null) {
        Log.i(TAG, "mListener not null");
        mListener.onDataUpdated(totalCount);
    }
    else
        Log.i(TAG, "mListener null"); // always come to this; the listener is null
    }
}

在我的主要 Activity 中,我实例化了监听器(在 onCreate 内部):

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // start listener for data update
    mNativeMgr = new NativeManager();
    mNativeMgr.registerListener(this);
    mNativeMgr.dataUpdate(0);
    ...
}

我认为这是因为在 native 部分,我实际上没有调用实例化的 Java 监听器对象,而是使用

jobject dataObjectHandle = env->NewObject(dataClassHandle, dataUpdateHandle);

在 void sendCount(int totalCount) 中。

我的问题是,如何在 C/C++ 代码中获取实例化的 Java 对象而不是创建一个新对象?谢谢大家,过去 2 天已经花在这上面了...

最佳答案

我找到了解决方案。我没有调用动态方法,而是将 Java 方法作为静态方法并使用 CallStaticVoidMethod 从 C++ 调用它。代码示例:

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }

    jclass dataClass = env->FindClass("com/example/crowdlogic/NativeManager");
    dataClassHandle = (jclass)env->NewGlobalRef(dataClass);
    dataUpdateHandle = env->GetStaticMethodID(dataClassHandle, "dataUpdate", "(I)V");
    return JNI_VERSION_1_6;
}

调用Java方法的 native 函数:

void sendCount(int totalCount) {

jint jtotalCount = totalCount;
jobject dataObjectHandle = env->NewObject(dataClassHandle, dataUpdateHandle);
if (dataObjectHandle == NULL) LOGI("dataObjectHandle null");
LOGI("init CallVoidMethod");
env->CallStaticVoidMethod(dataClassHandle, dataUpdateHandle, jtotalCount);
}

在Java中,我将方法声明为静态方法

关于java - 使用C++获取Java对象调用Java方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21549059/

相关文章:

java - java中的正则表达式字符类不一致

java - 从 MDX 请求 Mondrian 检索数据

android - 为什么 Android 不允许您在资源名称中使用大写字母?

Android 可以在 EditText 中绘制行号吗?

c++ - 无法将参数 1 从 'char' 转换为 'LPCWSTR'

c++ - PPP 状态机中 Closed 和 Stopped State 之间的确切区别是什么

C++ union 成员访问和未定义行为

java - <s :form> to decide in the action class 中的两个按钮

java - 为没有 Hibernate Annotations 的 PostgreSQL 文本类型更正 JPA Annotation

java - 从关系数据库检索数据