接着上一篇文章继续来说:
地址
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());
以上:仅仅只是自己写的代码 注释很多,代码质量不高,望谅解