Android的JNI【实战教程】4⃣️--C调用Java代码

来源:互联网 发布:淘宝二楼是干什么的 编辑:程序博客网 时间:2024/06/11 01:53

基本流程

非静态方法

得到字节码 (FindClass)
得到方法(GetMethodID)
实例化该类(AllocObject)
调用方法(CallIntMethod)

静态方法

得到字节码 (FindClass)
得到方法(GetStaticMethodID)
调用方法(CallStaticVoidMethod) 调用的静态方法

非静态方法

C代码调JAVA类中的addInt(int a, int b)方法

java代码:

    public int addInt(int a, int b){        int c = a+ b ;        Toast.makeText(MainApplication.getContext(),"计算结果:::"+c, Toast.LENGTH_SHORT).show();        return a+b;    }

.h代码:

JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackAddInt   (JNIEnv *env, jclass type);

c++代码:

/** * C代码调JAVA类中的addInt(int a, int b)方法 */JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackAddInt(JNIEnv *env, jclass type) {    //得到字节码    jclass jclazz = env->FindClass("com/libin/factory/ndk/Test"); //com.libin.factory.ndk.TestK 点换成下滑线    //得到方法    jmethodID jmethodIDS = env->GetMethodID(jclazz,"addInt","(II)I");    //实例化该类    jobject jobj = env->AllocObject(jclazz);    //调用方法    jint value =env->CallIntMethod(jobj,jmethodIDS,99,1);    LOGE("value = %d\n" ,value);}}

调用:

NDK.ccallBackAddInt();

展示:
这里写图片描述


C代码调JAVA类中的addInt(int a, int b)方法

java代码:

    public void setStrings(String s){        Toast.makeText(MainApplication.getContext(), s, Toast.LENGTH_SHORT).show();    }

.h代码:

JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackGetString        (JNIEnv *env, jclass type);

c++代码:

/*** C代码调JAVA类中的setStrign(String s)方法*/JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackGetString(JNIEnv *env, jclass type) {    //得到字节码    jclass jclazz = env->FindClass("com/libin/factory/ndk/Test"); //com.libin.factory.ndk.TestK 点换成下滑线    //得到方法    jmethodID jmethodIDS = env->GetMethodID(jclazz,"setStrings","(Ljava/lang/String;)V");    //实例化该类    jobject jobj = env->AllocObject(jclazz);    //调用方法    jstring str = env->NewStringUTF("hello 我是C,我在调用java方法");    env->CallVoidMethod(jobj,jmethodIDS,str);}

调用:

 NDK.ccallBackGetString();

展示:
这里写图片描述


静态方法

C代码调JAVA类中静态的addInt(int a, int b)方法

java代码:

    public static int addIntS(int a, int b){        int c = a+ b ;        Toast.makeText(MainApplication.getContext(), "计算结果:::"+c, Toast.LENGTH_SHORT).show();        return a+b;    }

.h代码:

JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackAddIntS        (JNIEnv *env, jclass type) ;

c++代码:

/*** C代码调JAVA类中的的addInt(int a, int b)静态方法*/JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackAddIntS(JNIEnv *env, jclass type) {    //得到字节码    jclass jclazz = env->FindClass("com/libin/factory/ndk/Test"); //com.libin.factory.ndk.TestK 点换成下滑线    //得到方法    jmethodID jmethodIDS = env->GetStaticMethodID(jclazz,"addIntS","(II)I");//    //实例化该类  (静态方法无需实例化该类)//    jobject jobj = env->AllocObject(jclazz);    //调用方法    jint value =env->CallStaticIntMethod(jclazz,jmethodIDS,99,1);    LOGE("value = %d\n" ,value);}

调用:

 NDK.ccallBackAddIntS();

展示:
这里写图片描述


静态方法

C代码调JAVA类中的setStringsS(String s)静态方法

java代码:

     public static void setStringsS(String s){        Toast.makeText(MainApplication.getContext(), s, Toast.LENGTH_SHORT).show();    }

.h代码:

JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackGetStringS        (JNIEnv *env, jclass type);

c++代码:

/*** C代码调JAVA类中的setStringsS(String s)静态方法*/JNIEXPORT void JNICALLJava_com_libin_factory_ndk_NDK_ccallBackGetStringS(JNIEnv *env, jclass type) {    //得到字节码    jclass jclazz = env->FindClass("com/libin/factory/ndk/Test"); //com.libin.factory.ndk.TestK 点换成下滑线    //得到方法    jmethodID jmethodIDS = env->GetStaticMethodID(jclazz,"setStringsS","(Ljava/lang/String;)V");//    //实例化该类 (静态方法无需实例化该类)//    jobject jobj = env->AllocObject(jclazz);    //调用方法    jstring str = env->NewStringUTF("hello 我是C,我在调用java的静态方法方法");    env->CallStaticVoidMethod(jclazz,jmethodIDS,str);}

调用:

NDK.ccallBackGetStringS();

展示:
这里写图片描述


对象的调用

C调java创建Student信息

java代码:
student类

     public class Student {    private String name;    private int age;    private List<People> peopleList;    public Student(){}    public Student(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "name --- >" + name + "  age --->" + age ;    }}

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    getStudentInfo * Signature: ()Lcom/libin/factory/ndk/Student; */JNIEXPORT jobject JNICALL Java_com_libin_factory_ndk_NDK_getStudentInfo  (JNIEnv *, jclass);

c++代码:

/** * 创建Student信息 */JNIEXPORT jobject JNICALLJava_com_libin_factory_ndk_NDK_getStudentInfo(JNIEnv *env, jclass type) {    //com.libin.factory.ndk.Student 要把 . 替换成 /    //关于包描述符,这儿是 com/libin/factory/ndk/Student 要用全类名    jclass stucls = env->FindClass("com/libin/factory/ndk/Student"); //或得Student类引用    //获得该类型的构造函数  函数名为 <init> 返回类型必须为 void 即 V    jmethodID constrocMID = env->GetMethodID(stucls, "<init>", "(Ljava/lang/String;I)V");    jstring str = env->NewStringUTF("Student named Aly");    jobject stu_ojb = env->NewObject(stucls, constrocMID, str, 25);  //构造一个对象,调用该类的构造函数,并且传递参数    return stu_ojb;}

调用:

Toast.makeText(JNIActivity.this, "Student信息 :" + NDK.getStudentInfo().toString(), Toast.LENGTH_SHORT).show();

展示:
这里写图片描述


C调java跟新Student信息

java代码:
student类

     public class Student {    private String name;    private int age;    private List<People> peopleList;    public Student(){}    public Student(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "name --- >" + name + "  age --->" + age ;    }}

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    updateStudentInfo * Signature: (Lcom/libin/factory/ndk/Student;)Lcom/libin/factory/ndk/Student; */JNIEXPORT jobject JNICALL Java_com_libin_factory_ndk_NDK_updateStudentInfo  (JNIEnv *, jclass, jobject);

c++代码:

/** * 跟新Student信息 */JNIEXPORT jobject JNICALLJava_com_libin_factory_ndk_NDK_updateStudentInfo        (JNIEnv *env, jclass type, jobject obj) {    jclass clazz;    jfieldID fid;    jstring j_str;    jstring j_newStr;    clazz = env->GetObjectClass(obj);    if (clazz == NULL) {        return NULL;    }    fid = env->GetFieldID(clazz, "name", "Ljava/lang/String;");    if (clazz == NULL) {        return NULL;    }    j_str = (jstring) (env)->GetObjectField(obj, fid);    j_newStr = (env)->NewStringUTF("This is New Name hahah");    (env)->SetObjectField(obj, fid, j_newStr);    // 删除局部引用    (env)->DeleteLocalRef(clazz);    (env)->DeleteLocalRef(j_str);    (env)->DeleteLocalRef(j_newStr);    return obj;}

调用:

Toast.makeText(JNIActivity.this, "Student信息 :" + NDK.updateStudentInfo(NDK.getStudentInfo()), Toast.LENGTH_SHORT).show();

展示:
这里写图片描述


下一篇我们介绍一下AS 2.2 以上配置NDK —-纵享丝滑
http://blog.csdn.net/github_33304260/article/details/71404510

7 0