-基础知识
NDK编程分为静态注册和动态注册两类。静态注册是指调用javah生成JNI头文件,然后用户包含该JNI头文件并实现要求的函数;静态注册中的函数满足一定的命名规则,这样实现了java中native函数到so文件的映射关系。动态注册是指在Jni_Onload()中调用RegisterNatives() JNI函数,来实现映射关系。
我们在实际开发中,有时候自己实现so源码并进行调用,有时候需要调用第三方so中的函数,这在流行的Android开发工具——Android Studio中有着不同的处理方式。
以下实验环境均为:Windows 7 64, Android Studio 1.5
-调用已编译的so:动态注册+jniLibs目录
首先,我们在Project视图中main文件夹下建立子文件夹jniLibs,然后将编译好的so文件按架构类型放入,即可直接调用。这种调用方法在Android 开发官方文档里提到过。
在这种情况下,so文件已经编译好,我们不能修改其中的函数来满足命名要求,所以静态注册不可行的,需要使用动态注册。具体而言,是在Jni_Onload()方法中调用RegisterNatives()方法来进行注册。
-C/C++开发so:gradle + 静态注册/ 动态注册
Android Studio中的gradle对NDK开发支持性较差,配置中容易出现很多问题,在此针对本人在环境配置中遇到的问题一一说明。
坑1:找不到jni.h
Android Studio 2.0上市后我迅速进行更新,然而却发现用javah生成的.h文件中存在“cannot find jni.h”的错误,致使完全无法进行NDK开发。Google后发现这是Android Studio 2.X的bug,主要问题是路径出错,开发人员在官方论坛上说会在Android Studio 2.2版本解决这个bug。在这里有两种解决方案,一种是使用Android Studio 1.5版本,另一种是使用gradle-experiment-rc-0.7.0版本,据说已经解决了这个bug。
这里我选择方法1,回退到Android Studio 1.5后可以正常运行。
坑2:抽风的显示错误
AndroidStudio,有时候像下图一样报错也能顺利运行。
坑3:关于android-support-v7-appcompat的错误
在静态注册的情况下,需要调用javah来生成JNI头文件。具体而言,这里有两种姿势:
(1)到/app/src/main/java 目录下执行命令:javah XXX.XX.XXX 即可, XXX.XX.XXX是要生成.h文件的完整路径名,包名+文件名
这种情况下不会出现和android-support-v7-appcompat有关的错误
(2)到/app/src/main目录下执行命令:javah -classpath XXX -jni -d jni XXX.XXX.XXX , XXX是编译中需要用到的jar包,这是网上教程中最普遍的说法。和上面生成.h文件的方法相比,结果会略有差别,但是均可以正常使用。
但是本人的环境下会出现和android-support-v7-appcompat有关的错误。网上说这种情况需要把android-support-v4.jar和android-support-v7-appcompat.jar两个包加入classpath路径,但在Android Studio自带的sdk包中并没有看到这两个文件,反而是在单独下载的sdk包中找到了。添加进去后可以顺利运行。
具体运行命令如下:
javah -d jni -classpath D:\Android\sdk\platforms\android-22\android.jar;D:\android-support-v4.jar;D:\android-support-v7-appcompat.jar;….\build\intermediates\classes\debug com.example.lucy.jnichecksign.MainActivity
-其他方式:如gradle-experimental
由于gradle对NDK开发的支持性不好,Android Studio官方推荐使用gradle-experimental for NDK 插件来代替gradle,具体参考[4]中的说明进行配置。
在此推荐第一种方法,配置简单、快捷、灵活、坑少。
-参考链接:
[1] http://www.xiaobaiyey.com/598.html
[2] http://www.androidchina.net/1691.html
[3] http://zhixinliu.com/2015/07/01/2015-07-01-jni-register/
[4] http://tools.android.com/tech-docs/new-build-system/gradle-experimental
[5] http://blog.k-res.net/archives/1788.html
[6] http://blog.csdn.net/sumakira/article/details/46548517
[7] http://www.jb51.net/article/65520.htm
[8] http://stormzhang.com/android/2015/03/29/android-support-library/