java和jni交互 之jni调用java静态方法,实例方法和修改成员变量

接着上一篇文章继续来说:
地址
https://mp.csdn.net/mdeditor/85546883#

交互之前,说几个概念性的东西:
jni调用思想:

    找到对应的类 -jclass
    找到对应的方法 -jmethonID
	调用相关方法 CallVoidMethid
	释放相关资源就行了

以及生成方法的签名,native方法,在生成头文件时 会自动带有注释,需要手动生成java文件的方法签名,方法如下:
在\app\build\intermediates\classes目录下输入如下命令:
javap -s 包名+类名 生成方法的签名

以及c调用java实例方法步骤:

1,找到对应的class  --findClass
 2,  然后调用其构造方法  GetMethodID
 3, 创建其对象  NewObject
 4,调用其方法

同样,第一步,编写java层代码的静态方法,实例方法,和字段

public class MyFirstJni {
    private String addRess = "beijing";
    private static String name = "nata";
    static {
        System.loadLibrary("firstC");
    }

    public static void loadMessage(String data){
        Log.d("data", data);
    }

    public void method(String data){
        loadMessage(data);
        loadMessage(addRess);
    }

    public static void staticMethod(String data){
        loadMessage(data);
        loadMessage(name);
    }
	
	//java调用jni
    public static native String getJniData();

    public static native void callStaticMethod(int c);

    public static native void callStaticMethod(long i,String str);

    public native void callInstanceMethod(int i);

    public native void callInstanceMethod(String str,long i);
}

第二步:生成头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_example_a13940_myapplication_MyFirstJni */

#ifndef _Included_com_example_a13940_myapplication_MyFirstJni
#define _Included_com_example_a13940_myapplication_MyFirstJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    getJniData
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_a13940_myapplication_MyFirstJni_getJniData
  (JNIEnv *, jclass);

/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    callStaticMethod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__I
  (JNIEnv *, jclass, jint);

/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    callStaticMethod
 * Signature: (JLjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__JLjava_lang_String_2
  (JNIEnv *, jclass, jlong, jstring);

/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    callInstanceMethod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__I
  (JNIEnv *, jobject, jint);

/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    callInstanceMethod
 * Signature: (Ljava/lang/String;J)V
 */
JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__Ljava_lang_String_2J
  (JNIEnv *, jobject, jstring, jlong);

#ifdef __cplusplus
}
#endif
#endif

第三步:编写cpp文件中调用java方法 和jni方法的具体实现

//
// Created by 13940 on 2019/1/1.
//

#include "com_example_a13940_myapplication_MyFirstJni.h"

//java调用jni方法
JNIEXPORT jstring JNICALL Java_com_example_a13940_myapplication_MyFirstJni_getJniData
  (JNIEnv * env, jclass jcls){
    return env->NewStringUTF("FORM C DATA");
  }

/*
 * Class:     com_example_a13940_myapplication_MyFirstJni
 * Method:    callStaticMethod
 * Signature: (I)V
 */
 //调用静态方法 和修改成员变量
JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__I
  (JNIEnv * env, jclass jclassess, jint i){
    //找到相关的类 注意路径是带反斜杆  不是带.
    jclass cls_First = env->FindClass("com/example/a13940/myapplication/MyFirstJni");
    if(cls_First == NULL){
        return;
    }

       /**
       方法参数:类名,方法名,方法签名
       */
    //找到对应的方法  注意签名后面有冒号
    jmethodID mtd_static_method = env->GetStaticMethodID(cls_First,"staticMethod","(Ljava/lang/String;)V");
    if(mtd_static_method == NULL){
        return;
    }

    //修改java中静态字段的值 获取成员变量  注意签名后面有冒号
    jfieldID file_name = env->GetStaticFieldID(cls_First,"name","Ljava/lang/String;");
    if(file_name == NULL){
        return;
    }
    //定义静态字段的值
    jstring name = env->NewStringUTF("TOM");
    //对成员变量设置值
    env ->SetStaticObjectField(cls_First,file_name,name);

    jstring data = env->NewStringUTF("call static method");
    if(data == NULL){
        return;
    }

    //调用java层静态方法
    env ->CallStaticVoidMethod(cls_First,mtd_static_method,data);

    //删除引用
    env->DeleteLocalRef(cls_First);
    env->DeleteLocalRef(name);
    env->DeleteLocalRef(data);

  }


  /*
   * Class:     com_example_a13940_myapplication_MyFirstJni
   * Method:    callInstanceMethod
   * Signature: (I)V
   */
   //调用java实例方法 和修改实例变量
  JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__I
    (JNIEnv *env, jobject jobj, jint i){

    //找到对应的方法
    jclass cls_First = env->FindClass("com/example/a13940/myapplication/MyFirstJni");
             if(cls_First == NULL){
                 return;
              }


        //找到对应的方法
         jmethodID mtd_method = env->GetMethodID(cls_First,"method","(Ljava/lang/String;)V");
         if(mtd_method == NULL){
            return;
         }

            //找到对应的构造方法
         jmethodID mtd_construct = env->GetMethodID(cls_First,"","()V");
         if(mtd_construct == NULL){
            return;
         }


        jfieldID fld_address = env->GetFieldID(cls_First,"addRess","Ljava/lang/String;");
        if(fld_address == NULL){
            return;
        }

        jstring address = env->NewStringUTF("shanghai");
        if(address == NULL){
            return;
        }

            //创建相应的对象
         jobject oFirst = env->NewObject(cls_First,mtd_construct,NULL);
         if(oFirst == NULL){
            return;
         }

        //注意此时的对象  应该是jobject对象 非jclass对象
        env->SetObjectField(oFirst,fld_address,address);

        jstring message = env->NewStringUTF("call instance method");

        //调用java层实例方法  注意此时的对象  应该是jobject对象 非jclass对象
        env->CallVoidMethod(oFirst,mtd_method,message);

        //清除对象的引用
        env->DeleteLocalRef(message);
        env->DeleteLocalRef(cls_First);
        env->DeleteLocalRef(oFirst);
        env->DeleteLocalRef(address);

    }

第四步:调用jni方法
new MyFirstJni().callInstanceMethod(2);
MyFirstJni.callStaticMethod(21);
viewById.setText(MyFirstJni.getJniData());

以上:仅仅只是自己写的代码 注释很多,代码质量不高,望谅解

你可能感兴趣的:(jni,jni,jni交互)