身为一个从事android的我,博客里一篇关于android的文章都没有,说来实属惭愧。我这里就简单说下关于jni的一个问题吧。
其实关于android的jni调用应该会经常遇到,比如跑一些算法之类的,如果想提升运行效率,还是得调用jni,其实编译成.so文件也算对自己的代码的保护。
那么问题就出现了,其实调用jni后的一些问题其实是不好定位的,尤其是不能像ios那种直接可以根据断点就能查找到病因。android里面有一个工具ndk-stack,当你配置好了
adb的环境变量后,就可以直接在AndroidStudio 的 Terminal 或者 直接在命令行的执行下面的语句
adb logcat | $NDK_HOME/ndk-stack -sym $PROJECT/libs/armeabi(armeabi-v7a)
如果提示 "adb不是内部或者外部命令,也不是可运行储蓄或批处理文件"的话,说明你的adb的环境变量没有配置。
找到你的sdk的目录 $Sdk_Path/platorm-tools 将这个路径配置到你的环境变量里面去就可以了。
正常的话就可以直接显示出你在.so里面 crash的原因了。
如果觉得还不够定位问题的原因的话,不嫌麻烦的同学可以在.so里面打印LOG
在头文件里面定义如下:
在你认为可能会出现问题的地方开始打印一些信息。当然,也仅仅是给自己一些提示,并不能打印出值。找到出现问题的行,然后进行修改就可以了。
这里给点可能出现问题的原因吧,方便读者分析:
1.malloc的大小是否足够,不足的话会造成数组越界。
Tip:可以申请的比你实际的稍大,多余的地方别操作就行了。
2.申请内存的是否进行了释放。
3.不要光认为在Java里面申请了byte[]后就可以直接用这段空间来进行后续操作,需要在.c文件里面进行赋值。
赋值如下:
(env)->GetByteArrayRegion (env, data, 0, data_len, (jbyte)(InC_data));
当然,返回值的时候也需要
(env)->SetByteArrayRegion (env, dst_data, 0,dst_data_len , (jbyte)(InC_dst_data));