Android studio NDK成長記錄(四)C調Java的各種情況解析

C調用Java的各種情況:
C調用Java代碼利用反射進行調用,jni.h中提供相應API,直接調用API進行調用。調用基本步驟如下:

  1. 得到需要調用的類的字節碼
  2. 得到方法的ID
    得到方法ID的時候調用GetMethodID(env, jclass1, "add_number", "(II)I");這個方法的最後一個參數是方法簽名,對方法簽名其實是對字節碼進行簽名,所以需要先在Java類中寫好方法,然後rebuild project,再進入build\intermediates\classes\debug目錄下,打開doc窗口執行‘javap -s + 全類名’ 命令,如“javap -s com.picovr.javacall.NativeMethord”:

  3. 實例化該類得到該類的對象
  4. 調用該方法

Java代碼:

package com.picovr.javacall;

import android.util.Log;

/**
 * Created by PICO-USER on 2017/1/18.
 */

public class NativeMethord {

    static {

        System.loadLibrary("native_jni");
    }

    public void helloFromJava() {

        Log.i("NativeMethord", "helloFromJava");

    }

    public int add_number(int x, int y) {

        Log.i("NativeMethord", "add_number add :" + x + "  y:" + y);
        return x + y;
    }
}

C代碼:

/*
 *調用Java中的add_number方法,對20和30進行加法運算
 */
JNIEXPORT jint JNICALL Java_com_picovr_javacall_NativeMethord_addNumberCallback
        (JNIEnv *env, jobject jobj) {

    //1.得到字節碼
    //jclass      (*FindClass)(JNIEnv*, const char*);
    jclass jclass1 = (*env)->FindClass(env, "com/picovr/javacall/NativeMethord");

    //2.得到方法ID
    //jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID jmethodID1 = (*env)->GetMethodID(env, jclass1, "add_number",
                                               "(II)I");//倒數第一個參數:方法簽名,倒數第二個參數:方法名

    //3.實例化類
    //jobject     (*AllocObject)(JNIEnv*, jclass);
    jobject jobject1 = (*env)->AllocObject(env, jclass1);

    //調用方法
    //jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
    jint result = (*env)->CallIntMethod(env, jobject1, jmethodID1, 20, 30);
    LogI("result :%d", result);
}

/*
 *調用java中的helloFromJava方法
 */
JNIEXPORT jint JNICALL Java_com_picovr_javacall_NativeMethord_getStringCallback
        (JNIEnv *env, jobject jobj) {

    //1.得到字節碼
    //jclass      (*FindClass)(JNIEnv*, const char*);
    jclass jclass1 = (*env)->FindClass(env, "com/picovr/javacall/NativeMethord");

    //2.得到方法ID
    //jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID jmethodID1 = (*env)->GetMethodID(env, jclass1, "helloFromJava",
                                               "()V");//倒數第一個參數:方法簽名,倒數第二個參數:方法名

    //3.實例化類
    //jobject     (*AllocObject)(JNIEnv*, jclass);
    jobject jobject1 = (*env)->AllocObject(env, jclass1);

    //調用方法
    //jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env, jobject1, jmethodID1);
    LogI("Java_com_picovr_javacall_NativeMethord_getStringCallback");
}
發佈了34 篇原創文章 · 獲贊 23 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章