Android NDK開發:C創建Java層的對象

目錄

相關文章

Android NDK開發:java調用dll動態鏈接庫方法
Android NDK開發:JNIEnv的原理
Android NDK開發:C修改Java的屬性
Android NDK開發:C調用Java層方法

C創建Java層的對象

1.根據class對象創建
這種創建方式需要Java層傳遞calss對象給C語言層,具體如下:
Java代碼

public static native NdkDemo createJavaObj(Class clazz);

C語言代碼

JNIEXPORT jobject JNICALL Java_com_itfitness_NdkDemo_createJavaObj
(JNIEnv* env, jclass jclazz, jclass create_jcalzz) {

    char* method_name = "<init>";
    char* method_sign = "()V";
    //構造方法
    jmethodID constructor_method_id = (*env)->GetMethodID(env,create_jcalzz,method_name,method_sign);

    //創建對象
    jobject jobj = (*env)->NewObject(env,create_jcalzz, constructor_method_id);

    //獲取對象的printStr方法
    jmethodID print_method_id = (*env)->GetMethodID(env, create_jcalzz, "printStr", "(Ljava/lang/String;)V");

    //創建jstring類型的參數
    jstring param = getJstring(env,"我是C語言傳過來的打印參數", "GB2312");

    //調用對象的printStr方法
    (*env)->CallVoidMethod(env,jobj, print_method_id,param);

    return jobj;
}

其中getJstring方法也是我在網上找的方法,主要是因為用NewStringUTF方法生成的字符串在idea的控制臺亂碼,getJstring方法如下:

jstring getJstring(JNIEnv* env, const char* pat, const char* encod)
{
    //定義java String類 strClass
    jclass strClass = (*env)->FindClass(env, "Ljava/lang/String;");

    //獲取java String類方法String(byte[],String)的構造器,用于將本地byte[]數組轉換為一個新String
    jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V");

    //建立byte數組
    jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat));

    //將char* 轉換為byte數組
    (*env)->SetByteArrayRegion(env, bytes, 0, strlen(pat), (jbyte*)pat);

    // 設置String, 保存語言類型,用于byte數組轉換至String時的參數
    jstring encoding = (*env)->NewStringUTF(env, encod); 

    //將byte數組轉換為java String,并輸出
    return (jstring)(*env)->NewObject(env, strClass, ctorID, bytes, encoding);
}

執行結果如下


2.根據類的簽名創建
這種方法是先根據類的簽名來獲取class對象,后面的步驟跟上面的都一樣,具體如下:
Java代碼

public static native NdkDemo createNdkDemoObj();

C語言代碼

JNIEXPORT jobject JNICALL Java_com_itfitness_NdkDemo_createNdkDemoObj
(JNIEnv* env, jclass jclazz) {

    //找到class對象
    jclass ndkdemo_clazz = (*env)->FindClass(env, "Lcom/itfitness/NdkDemo;");

    char* method_name = "<init>";
    char* method_sign = "()V";
    //構造方法
    jmethodID constructor_method_id = (*env)->GetMethodID(env, ndkdemo_clazz, method_name, method_sign);

    //創建對象
    jobject jobj = (*env)->NewObject(env, ndkdemo_clazz, constructor_method_id);

    //獲取對象的printStr方法
    jmethodID print_method_id = (*env)->GetMethodID(env, ndkdemo_clazz, "printStr", "(Ljava/lang/String;)V");

    //創建jstring類型的參數
    jstring param = getJstring(env, "我是C語言通過類的簽名創建的對象", "GB2312");

    //調用對象的printStr方法
    (*env)->CallVoidMethod(env, jobj, print_method_id, param);

    return jobj;
}

執行結果如下


?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容