![手把手教你开发jni_java](https://s2.51cto.com/images/blog/202106/16/61e1425316dfc2fdb6f6708c1afb42cb.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
开发环境:Androidstudio2.3
开发目的:在Androidstudio上编译c/C++jni并自动生成so库,在Java类中引用。
开发过程中遇到的问题很多,但终归是成功了,记录下来用Androidstudio的准备
遇到的问题诸如:
![手把手教你开发jni_java_02](https://s2.51cto.com/images/blog/202106/16/3f0c8beba213b11b39c4fe9306403d2b.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_03](https://s2.51cto.com/images/blog/202106/16/b6dc029521e9f1b3373c37c81bb407c6.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_04](https://s2.51cto.com/images/blog/202106/16/1c00b930bbe4e8b86b8b35d8ad40b9dd.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_05](https://s2.51cto.com/images/blog/202106/16/7de858dc4d31418b19eb7c6b373e252b.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_06](https://s2.51cto.com/images/blog/202106/16/4af159decd881b8b29746d9098c2f05e.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
最后当问题结束后,so包一直不出来。
好不容易so包打出来了,java文件却提示找不到,我也是无语了。但幸好问题一个一个的解了
![手把手教你开发jni_java_07](https://s2.51cto.com/images/blog/202106/16/185259a56235249f4711a762a58c6e26.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_08](https://s2.51cto.com/images/blog/202106/16/11c247b6081658982b8009469270c964.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
01
ndk的下载安装&配置
对于ndk的下载有两种方式:
第一:Androidstudio中在线下载安装:这个还是很简单的,我是在用到jni时提示我需要ndk,然后点击安装,速度很快,而且Androidstudio中需要配置ndk的一些gradle文件中也会连带着给配置了,很方便。
第二:下载到本地/安装: 如果这么做也就表示你要做一下几步:
第一步:下载ndk
首先你要在网上找到ndk的下载地址:https://developer.android.google.cn/ndk/downloads/index.html
第二步:正确安装
软件安装这个不再多说....
第三步:配置ndk
在Androidstudio中像配置jdk一样配置ndk。打开as-->file-->Project structure配置ndk的路径,如下图所示
![手把手教你开发jni_java_09](https://s2.51cto.com/images/blog/202106/16/c026e3ec66225997471afec7c99013ed.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
第四步:开发配置
配置gradle.properties 文件,目录结构选择project,配置project的gradle.properties文件
![手把手教你开发jni_java_10](https://s2.51cto.com/images/blog/202106/16/5b4b5b7897070c5cc13047601a95e063.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
在该文件中添加android.useDeprecatedNdk=true,如下图所示:
![手把手教你开发jni_java_11](https://s2.51cto.com/images/blog/202106/16/0f1797424cbb24e7b186648c99054f51.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
第五步:开发配置
配置local.properties文件,文件目录和所修改的gradle.properties同级。添加ndk的声明引用ndk.dir=E\:\\zrf\\tools\\work\\installed\\Android\\sdk\\ndk-bundle 如下图所示:
![手把手教你开发jni_java_12](https://s2.51cto.com/images/blog/202106/16/b273f10c0587f1d698d31b66ef695ebc.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
02
ndk的环境变量
对于ndk,需要在环境变量Path中声明:
-
首先定义一个变量NDK_ROOT,指向ndk的安装路径:E:\zrf\tools\work\installed\Android\sdk\ndk-bundle
-
在path中添加声明ndk的变量%NDK_ROOT%;
其实你定义的变量名字是什么都无所谓,只要保证path中包含ndk的安装路径即可。
定义环境变量的意义就是可以在cmd中使用ndk-build命令进行手动编译。
02
开发JniDemo
经过以上两步后,ndk的环境搭建基本就完成了,接下来就是demo验证了:
1新建java文件: 在src\main\java\com\android\jnidemo目录下新建JniUtils.java
![手把手教你开发jni_java_13](https://s2.51cto.com/images/blog/202106/16/9b509cd5f9b64a0741af11d52b15ab85.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
2
生成.h文件:该步分为两步,第一找到JniUtils.class所在路径,第二在as的terminal终端中执行javah命令,生成对应的.h文件。
01
找到class的路径
JniUtils.class路径:E:\zrf\project\as_project\JniDemo\app\build\intermediates\classes\debug\com\android\jnidemo\JniUtils.class。
![手把手教你开发jni_java_15](https://s2.51cto.com/images/blog/202106/16/e71bdc40951945be626bf3d9fec853a9.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
JniUtils.java的文件内容为:
![手把手教你开发jni_java_16](https://s2.51cto.com/images/blog/202106/16/aca0385fb7f4266cc4a5e46949567163.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
在该文件中System.loadLibrary用于加载so文件,这里不需要so后缀,也不需要加lib前缀
02
![手把手教你开发jni_java_17](https://s2.51cto.com/images/blog/202106/16/d46ec5b1da208427ebf3691a257d08bf.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
在终端执行命令生成.h文件:javah -d classpath classpath E:\zrf\project\as_project\JniDemo\app\build\intermediates\classes\debug com.android.jnidemo.JniUtils.class 注意该命令在debug后有空格,命令之所以这么写是跟jni的名字命名有关。
![手把手教你开发jni_java_18](https://s2.51cto.com/images/blog/202106/16/25f437b827371c38a67702bb9e871c27.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
运行命令后,可以看到在src/main/目录下自动生成了jni文件夹,文件夹中有一个文件
![手把手教你开发jni_java_19](https://s2.51cto.com/images/blog/202106/16/1b8a65f277f04f0693487471612a93c8.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
.h文件内容为:
![手把手教你开发jni_java_20](https://s2.51cto.com/images/blog/202106/16/46070bf000b058dbb91a7fe43bc124c0.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
3
新建.c文件
在jni目录下新建.c文件,命名无所谓,内容仿照.h文件来:
![手把手教你开发jni_java_21](https://s2.51cto.com/images/blog/202106/16/d2ff484af6da7b387a86a80a4808f9ad.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
4
新增Android.mk文件
在jni目录下新增Android.mk文件(选定jni目录后右键-file(在填写file的name时添加mk后缀)),mk文件内容为:
![手把手教你开发jni_java_22](https://s2.51cto.com/images/blog/202106/16/b823ff6e0547c7d8c3b0fd5c8f166e7e.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
在mk文件中有两个参数需要注意,一是LOCAL_MODULE:声明的为jni模块名,即所生成的so文件的名称。二是LOCAL_SRC_FILES:为.c文件相对mk文件的路径
5
新增Application.mk文件
![手把手教你开发jni_java_23](https://s2.51cto.com/images/blog/202106/16/294d3c8edb0193c59608f74c519b553a.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
在jni目录下新增Application.mk文件(同android.mk文件),文件内容如上
6
配置buld_grdle
接下来就是配置编译环境了:
![手把手教你开发jni_java_24](https://s2.51cto.com/images/blog/202106/16/971453843511e0f2e2286fcab29d77af.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![手把手教你开发jni_java_25](https://s2.51cto.com/images/blog/202106/16/ad4042054b1eff9dfb975984895b0751.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
需要配置两大部分,参考图中注释可以看出各部分有何含义。注意,如果你在gradle中配置了jni.srcDirs,那么as就不会自动生成so库了,所以如果想要as自动生成so文件,千万不要进行如上配置:说这个是因为很多文章直接写出了这个配置,误导了很长时间。。。
7
so文件的位置
生成的so文件的位置为 :
E:\zrf\project\as_project\JniDemo\app\build\intermediates\ndkBuild\debug\obj\local\armeabi
![手把手教你开发jni_java_26](https://s2.51cto.com/images/blog/202106/16/bbe11bf5a1df5a24989fd3fddb071103.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
04
Demo验证
在本应用中使用应用内的jni进行验证
在MainActivity中调用JniUtils中的native方法进行验证:
![手把手教你开发jni_java_27](https://s2.51cto.com/images/blog/202106/16/6659d92fb9694845cbe1591976333779.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
验证结果:
https://mp.weixin.qq.com/s/WVbU61oDH_lRosWHOhO_uQ