JNI之初长成(一)

一,概述

由于公司项目用到jni(java native interface),所以小小的研究一下,我们平时引用一些第三方sdk时,有时会用到so库,即底层调用C/C++代码,此时第三方已经封装好,展现在我们面前的是java层代码,我们只需要调用即可,下面就来一遍我们自己生成so文件.
我认为有这么几个步骤:
 1,下载ndk,配置ndk环境变量
 2,编写java方法代码
 3,利用命令生成.h文件
 4,编写.c文件
 5,生成so,java层实现调用C方法

二,实现

1, 下载ndk,配置ndk环境变量

关于ndk的下载,由于我现在用的是Android Studio2.3.1,直接使用AS下载,点击这里写图片描述,进入Android SDK,这里写图片描述,,这里可直接下载NDK,接下来配置ndk环境变量,类似jdk配置,可自行百度,这里不再赘述

2,编写java方法代码

直接上代码,这里建议有个专门的类管理native方法,
public class MyJniUtils {

public native String getString();

}
一般我们声明调用C的方法,都用native关键字,这里返回的是string类型

3,利用命令生成.h文件

重点来了,生成.h头文件,上述第二步代码编写完成后,Rebuild Project,这样MyJniUtils的.class文件就生成在了如下目录:这里写图片描述
Terminal定位到debug目录,输入:javah -jni MyJniUtils所在包的包名.MyJniUtils
如下:
这里写图片描述,至此,.h文件生成,在debug目录下,如图:
这里写图片描述

4,编写.c文件

mian目录下建立jni文件夹,将第4步生成的.h文件拷过来,新建jniTest.c文件,这里可自由取名
这里写图片描述
我们看到.h文件中已经帮我们生成好了jniTest.c文件的方法名,直接拷贝,头文件引入
#include “cn_junjun_com_jnidemo_MyJniUtils.h”
jniTest.c具体代码:

#include “cn_junjun_com_jnidemo_MyJniUtils.h”

JNIEXPORT jstring JNICALL Java_cn_junjun_com_jnidemo_MyJniUtils_getString
(JNIEnv* env, jobject obj) {
return (*env)->NewStringUTF(env,”Hello from C”);
}
至此,简单的.c文件编写完成
这里写图片描述

5,生成so,java层实现调用C方法

我们最期待的来了,生成so库
build.gradle里面的defaultConfig中,添加
ndk{
moduleName “MyJni” //生成的so名字
abiFilters “armeabi”, “armeabi-v7a”, “x86” //输出指定三种abi体系结构下的so库。
}
,比以前的使用cmake方便很多,直接Rebuild Project,就会在build->intermediates->ndk->debug->lib下生成我们想要的so库啦,上图:
这里写图片描述
将生成的lib下的文件拷入项目libs文件夹或者jnilibs文件夹就可以使用了.
其中MyJniUtils加入加载so库的方法如图:
这里写图片描述
java层现在就可以调用C层的方法了,
TextView tv = (TextView) findViewById(R.id.sample_text);
MyJniUtils jni = new MyJniUtils();
tv.setText(jni.getString());
这里写图片描述

6,坑坑坑

这里说两个坑:
第一:如果无法生成so库,请在jni文件里添加一个空的util.c,至于为什么,我也不知道,应该是一个bug
第二:我在生成so过程中出现如下错误:
Error:(115) * Android NDK: Aborting . Stop.
Error:Execution failed for task ‘:app:compileDebugNdk’.
> com.android.ide.common.process.ProcessException: Error while executing process D:\huangwenjun\soft\sdk\ndk-bundle\ndk-build.cmd with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\huangwenjun\workspace\MydemoWorkspace\JniDemo\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-25 NDK_OUT=D:\huangwenjun\workspace\MydemoWorkspace\JniDemo\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=D:\huangwenjun\workspace\MydemoWorkspace\JniDemo\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi-v7a,armeabi,x86}

我把build.gradle中的compileSdkVersion和targetSdkVersion都改成24就可以了,之前是25,可能是版本的问题吧,但是用24生成so之后,再改回25,方法依然是可以调用的

至此完结

说了这么多,有不完善的地方,欢迎大家指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值