[Android ]JNI 入门踩坑

时间:2024-03-28 17:20:35

文章转自:[Android ]JNI 入门踩坑

很久以前玩了一下NDK的编译,那时候还是Eclipse时代。

现在都换成Android studio时代,当然就要换新工具啦。

普通的配置的方法,太多文章做基础配置的介绍了,我这里就不重复介绍。

史上最详细Android Studio + NDK范例

说一下踩坑当中遇到的问题吧。

(1)ndk的配置

ndk命令的环境配置,一开始想想觉得很简单。

但是当手写多次都有问题之后,最后还是使用复制粘贴其他环境变量的(特别是符号大小写的问题)

[Android ]JNI 入门踩坑

(2)低版本的NDK编译问题

NDK编译版本过低的时候会提示这个

[Android ]JNI 入门踩坑

网上很多资料都是在gradle.properties中添加一个Android.useDeprecatedNdk=true,

然而这样还是无法解决问题的。。。

其实这里一定要用android.useDeprecatedNdk=true(android一定要小写。)

[Android ]JNI 入门踩坑

(3)指定资源文件

网上都是指定这样的资源文件,你又理解这两个参数所表达的意思吗?

[Android ]JNI 入门踩坑

jni.srcDirs指的是需要编译的xx.c文件的地址

jniLibs.srcDir指的引用的xx.so文件的地址

如果你按上图这样填,你绝对会被坑死。。。编译出来连NDK的文件夹都不会出现。

[Android ]JNI 入门踩坑

jni.srcDirs=[]是不可行的,一定要指定好c文件的路径

[Android ]JNI 入门踩坑

对应的目录地址一定要有xx.c的文件

[Android ]JNI 入门踩坑

这样才能生成ndk的文件夹,ndk文件里面才是生成so文件,用于apk中jni的运行。

[Android ]JNI 入门踩坑

到达这里你编译app的时候,就会将so的文件放到你apk的lib文件夹里面

[Android ]JNI 入门踩坑

(4)开发中需要注意的是

类型转换,是真的要了解清楚,现在类型转换都已经比较智能了,只需要在前面加个jxxx(xxx为java数据类型)就是转换的类型了

[Android ]JNI 入门踩坑

(5)Android studio无法调试JNI里面的代码,其断点是无效的,所以必要的时候,一定要将必要参数打log

这里提供打log封装的方法,需要引用android/log.h的库,然后用define定义__android_log_print的打印方法。其参数和等级很容易在方法中辨认。

[Android ]JNI 入门踩坑
调用起来也非常简单,只需要使用上面的方法
[Android ]JNI 入门踩坑
调试台打log
[Android ]JNI 入门踩坑

(6)库引用相关

倘若xxx.c文件和对应的引用的xxx.h文件放到同一个文件夹里面

[Android ]JNI 入门踩坑
无需在c文件里面编写include h的头文件就可以使用h中定义的方法。
[Android ]JNI 入门踩坑

(7)Android生命周期产生的问题。

Java调用c的,需要jni提供接口就可以调用了。

c调用java的情况,一般是需要c使用反射的方法,创建相关对象和方法,然后填入方法参数调用的。

但是有个问题,因为Android的Activity和Fragment,Service等,其拥有生命周期的特殊性,我们无法直接反射生成一些需要持有上下文context的方法。那我们需要如何处理呢?

这里需要表明一下,我们每个JNI的方法都有两个变量

JNIEnv是上下文,jobject是调用这个方法的对象

[Android ]JNI 入门踩坑
那么调用Activity的方法,就利用jobj这个对象来调用方法即可。这里方法调用的方法自己还是查一下(jni.h和jni接口说明文档吧)
[Android ]JNI 入门踩坑

暂时踩坑情况就到这里。


***2017.3.15*****

群内有同学反映有其他问题,如果使用高版本的Android SDK编译后,如果切换到低版本的SDK例如(25->23)会出现崩溃的问题。

[Android ]JNI 入门踩坑

这是个开端,之后会继续深入给大家介绍JNI的内容。

敬请期待下期内容吧!!!