JNI 创建jobject的方法

如果你想要在C或C++中创建一个Java对象,你需要使用JNIEnv提供的方法。

1、NewObject 方法

这个方法需要三个参数:一个类引用(jclass),一个构造函数Id(jmethodID),以及构造函数需要的参数。

复制代码
// 1. 获取Person对应的jlcass对象
jclass person_clazz = env->FindClass("com/example/helllojni/Person");
if (person_clazz == nullptr) 
{
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Couldn't find com/example/helllojni/Person");
    return nullptr;
}

// 2. 获取构造函数的jmethodID
jmethodID person_constructor = env->GetMethodID(person_clazz, "<init>", "(Ljava/lang/String;I)V");
if (person_constructor == nullptr) 
{
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Couldn't find Person(String name, int age) constructor.");
    return nullptr;
}

// Person构造函数需要一个String参数,所以需要创建一个jstring
jstring name = env->NewStringUTF("David");

// 3. 调用构造函数创建Person对象,并返回给Java层
return env->NewObject(person_clazz, person_constructor, name, 18);
复制代码

通过使用 NewObject ,你可以在 C++ 代码中创建 Java 对象并调用其方法。这在需要从本地代码与 Java 代码交互时非常有用。

2、AllocObject 方法

这个方法只需要一个类引用(jclass),它会为对象分配内存,但不会调用构造函数。

复制代码
// 获取 MyClass 的类引用
jclass myClass = env->FindClass("com/example/yourapp/MyClass");
if (myClass == nullptr)
{
    LOGI("Failed to find MyClass");
    return;
}

// 使用 AllocObject 分配 MyClass 的实例
jobject myClassInstance = env->AllocObject(myClass);
if (myClassInstance == nullptr)
{
    LOGI("Failed to allocate MyClass instance");
    return;
}

// 获取 message 字段的 ID
jfieldID messageField = env->GetFieldID(myClass, "message", "Ljava/lang/String;");
if (messageField == nullptr)
{
    LOGI("Failed to find message field");
    return;
}

// 创建一个 Java 字符串对象
jstring message = env->NewStringUTF("Hello from C++");

// 设置 message 字段的值
env->SetObjectField(myClassInstance, messageField, message);

// 调用 printMessage 方法
jmethodID printMethod = env->GetMethodID(myClass, "printMessage", "()V");
if (printMethod == nullptr)
{
    LOGI("Failed to find printMessage method");
    return;
}

env->CallVoidMethod(myClassInstance, printMethod);


// 释放局部引用
env->DeleteLocalRef(message);
env->DeleteLocalRef(myClassInstance);
env->DeleteLocalRef(myClass);
复制代码

通过使用 AllocObject ,你可以在 C++ 代码中分配 Java 对象的实例,而不调用构造函数。这在需要手动初始化对象的字段时非常有用。

3、NewLocalRef 方法

复制代码
JNIEXPORT void JNICALL Java_com_example_MyClass_myNativeMethod(JNIEnv *env, jobject obj)
{
    // 获取对象的类
    jclass cls = env->GetObjectClass(obj);

    // 获取方法ID
    jmethodID mid = env->GetMethodID(cls, "myMethod", "()V");

    //创建局部引用
    jobject localRef = env->NewLocalRef(obj);
    
    // 调用方法  
    env->CallVoidMethod(localRef , mid);
}
复制代码

通过使用 NewLocalRef ,获取Java对象的局部引用。

 

 
posted @ 2025-08-15 18:58  tomato-haha  阅读(16)  评论(0)    收藏  举报