序章:
1.本篇是JNI入门教程的第六篇,完整教程连接如下:
JNI入门课程-序章https://blog.csdn.net/rzleilei/article/details/122084609
2.本篇主要考察的是各种数据类型的转换,要完成的需求如下:
java层传入一个文件的地址,在JNI层读到其中的内容,然后返回给JAVA层展示。
一。流程步骤
本章中执行流程主要包含以下几个步骤:
1.在java中声明引用。
2.创建jni方法,并在cpp文件中进行动态注册。
3.在CMakeLists中进行声明,声明之后jni中的方法才能被java外部调用。这步骤不介绍了,同上一篇。
4.java层中构造各种数据类型,然后传给JNI进行调用。
二。在java中声明引用
这个和上一篇一样,只是增加了一个实现native方法。
public class DynamicRegister {
static {
System.loadLibrary("DynamicRegister");
}
/**
* 拼接字符串str1和str2
* @param str1
* @param str2
* @return
*/
public native String spliceString(String str1,String str2);
/**
* 读取指定路径的文件内容
* @param path
* @return
*/
public native String readStrByPath(String path);
}
三。创建JNI的方法,并动态注册
1.创建JNI中的方法,传入参数path为jstring类型,返回为读取到的内容,jstring类型。
jstring nativeReadStrByPath(JNIEnv *env, jobject object, jstring path) {
const char *str = env->GetStringUTFChars(path, JNI_FALSE);
FILE *file = fopen(str, "r");
LOGI("content%","111");
__android_log_print(ANDROID_LOG_INFO, "lxltestjni", "111");
if (file == NULL) {
LOGI("null2");
}
std::string result;
char buffer[1024] = {0};
while (fread(buffer, sizeof(char), 1024, file) != 0) {
LOGI("%s","content");
result += buffer;
}
return env->NewStringUTF(result.c_str());
}
方法中,首先把jstring转为C中的字符串类型char
然后使用fopen生成文件指针,
然后使用fread不断的读取内容到result中,最终返回result。
2.对刚才创建的方法进行动态注册
static JNINativeMethod method_table[] = {
// 第一个参数a 是java native方法名,
// 第二个参数 是native方法参数,括号里面是传入参的类型,外边的是返回值类型,
// 第三个参数 是c/c++方法参数,括号里面是返回值类型,
{"spliceString", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (jstring *) nativeSpliceString},
{"readStrByPath", "(Ljava/lang/String;)Ljava/lang/String;", (jstring *) nativeReadStrByPath},
};
四。CMakeLists中做好声明
1.创建文件Cmake文件,同上一章,略。
五。验证效果
因为如果读取SD卡文件的话,还要额外申请权限。所以这里我们简单一点,先创建一个文件,然后写入hello world内容。然后通过JNI去读取。
1.data/file目录下,生成文件,并写入内容
val file = File(filesDir.absolutePath + File.separator + "a.txt")
IOHelper.writerStrByCodeToFile(file, "utf-8", false, "hello world")
2.java中调用JNI方法
if (position == 4) {
val file = File(filesDir.absolutePath + File.separator + "a.txt")
IOHelper.writerStrByCodeToFile(file, "utf-8", false, "hello world")
val readStrByPath = dynamicRegister.readStrByPath(file.absolutePath)
mResult.text = "$readStrByPath"
return
}
3.点击JNI读取文件,查看效果,这时候我们发现result中显示了从文件中读取的内容,如下图:
附:项目地址和源码
android_all_demo/DemoClient at master · aa5279aa/android_all_demo · GitHub