学习记录 2020/7/9

研一


ndk安装

因为要对c语言编写的程序打包,所以得安装NDK。但说是安装,其实不过是把包下载后设置一下环境变量。环境变量不能包含空格,网虽然有说把空格的路径用双引号括起来就好,但windows路径是不允许添加双引号的。

jni

jni学习首先要会写java文件,然后根据java编写相应的jni的.c,.h文件。最后仍需要通过java脚本的具体调用来验证编译结果是否正确。
按照10个示例完成了jni的学习:
示例一:在jni中调用标准C库函数:

Public native void print();
System.loadLibrary(“JNIExamples”);

示例二:在jni中调用自己编写的C函数:
和调用标准C库函数完全一样,jni检测不出哪个是标准库函数,哪个是个人写的函数。

示例三:在jni中访问java类中的对象实例域

jclass class_Field = (*Env)->GetObjectClass(env,obj);
jfieldID fdA = (*env)->GetFieldID(env, class_Field, “a”, “I”);
jint valueA = (*env)->GetIntField(env, obj, fdA);
(*env)->SetIntField(env, obj, fdA, 423);

示例四:在jni函数中访问类的静态实例域
静态域中的方法和实例不可访问非静态域中的东西,其在初始化时即被复制到堆中,所有线程都可对其进行访问。被static声明的静态实例域不是一个对象,是属于某一个类,其唯一定义且不可重复。猜测FindClass()函数的作用是在堆中查找,找到该静态实例域的具体内存地址。

jclass class_Field = (*env)->FindClass(env, “Field”);
jfieldID fdA = (*env)->GetStaticFieldID(env, class_Field, “a”, “I”);
jint valueA = (*env)->GetStaticField(env, class_Field, fdA);
(*env)->SetStaticField(env, class_Field, fdA, 423);

示例五:在jni函数中调用java对象的方法
jni是连接C和java的中间层,其功能是执行数据转换。jni对C更加友好一点,因为它就是C语言编写出来的,只要包含了头文件,就可以直接调用C中的函数,而对于java函数则需要一些变化((*env)->GetIntField(…)等)。
在jni函数中有时需要调用java中类对象已经实现的方法。

jclass class_CommonMethod = (*env)->GetObjectClass(env, obj);
jmethodID md = (*env)->GetMethodID(env, class_COmmonMethod, “print”, “(ILjava/lang/String;)V”);
(*env)->CallVoidMethod(env, obj, md, a, s);

示例六:在jni中调用java的静态方法

jclass class_Method = (*env)->FindClass(env, “Method”);
jmethodID md = (*env)->GetStaticMethodID(env, class_Method, “print”, “()V”);
(*env)->CallStaticVoidMehod(env, class_Method, md)

示例七:在jni函数中传递基本数据类型参数

jclass class_Basic = (*env)->GetObjectClass(env, obj);
jfieldID fd = (*env)->GetFieldID(env, class_Basic, “value”, “I”);
jint v = (*env)->GetIntField(env, obj, fd);
v += 423;
(*env)->SetIntField(env, obj, fd, v);

示例八:在jni函数中传递对象类型参数

jclass class_book = (*env)->GetObjectClass(env, objwhatever);
jmethodID id_getTotal = (*env)->GetMethodID(env, class_book, “getTotalPage”, “()I”);
jmethodID id_getCurrent = (*env)->GetMethodID(env, class_book, “getCurrentPage”, “()I”);
jint total_page = (*env)->CallIntMethod(env, objwhatever, id_getTotal);
jint current_page = (*env)->CallIntMethod(env, objwhatever, id_getCurrent);

示例九:在jni函数中处理字符串

const char *string = (char *)(*env)->GetStringUTFChars(env, s, NULL);
printf("%s\n", string);
(*env)->ReleaseStringUTFChars(env, s, (jbyte *)string);

示例十:在jni函数中处理数组

jint *arr = (*env)->GetIntArrayElements(env, intArray, NULL);
n = (*env)->GetArrayLength(env, intArray);
printf(“the native method output the int array\n”);
for (i = 0; i < (*env)->GetArrayLength(env, intArray); ++i) {
printf("%d", arr[i]);
(*env)->RealeaseIntArrayElements(env, intArray, arr, 0);
}

学习方法

先对知识框架有一个大概了解,然后具体深入到细节原理的学习是很有效的学习方法。满足这种流程的学习过程还有读书:先读薄再读厚;上学:先读研再读博;编程库的学习:先看看示例文件再针对每一行程序逐个击破……先对知识框架有个了解可以缓解深入学习时候不知所云的状况,而后面深入到原理的学习相对来说才更关键。在刚刚开始学习的时候如果不理解一个东西就先背下来,随着后面的学习,对前面的理解会更加深入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值