JNI即Java Native Interface (Java本地接口),用来实现java代码调用C/C++代码
先前跟着吾爱一大哥的帖子做了一遍没有成功,应该是他的版本过于老旧,于是自己进行尝试。
安装LLDB和CMake
在Android Studio的File->Settings->System Settings->Android SDK->SDK Tools
中选中LLDB和CMake进行安装
进行编写
创建新的Project
在选择Template时选Native C++看见报错提示Caused by: org.gradle.api.InvalidUserDataException: NDK not configured…
这是因为未选定NDK路径,于是进入File->Project Structure->SDK Location
中选择自己的NDK安装文件夹
点击OK之后会发现底部框框出现CONFIGURE SUCCESSFUL字样,此时NDK配置完成
新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。
使用javac编译上述文件,生成class文件
打开下方的Terminal即可进行编译,语句:javac E:\...\myJNI.java
,之后便会多出个myJNI.class文件进入java文件夹目录,并在里面执行
javah -jni 包名.类名
,然后会多出个包名_类名.h
将之前生成的.h文件移入cpp文件夹中,然后在其中创建一个新的.c或.cpp文件。将.h文件中的内容复制进入并作修改,如下:
此时文件上方也许 会有报错提示,不用理会
配置build.gradle文件,如下图:
修改CMakeList.txt文件,如下图:
生成SO库
点击Build->Rebuild Project
即可,生成的各版本的so都在app->build->intermediates->cmake->debug->obj
文件夹中
调用SO
新建jniLibs文件夹,将生成的so拷入
打开MainActivity.java插入一条log来调用so中的sayHello方法(如下图),并连接手机调试
运行出现
More than one file was found with OS independent path 'lib/x86/libJniTest.so'
报错,原来是因为把各版本的so都拷入的原因,删掉其他三个,运行成功若出现
More than one file was found with OS independent path 'lib/armeabi-v7a/libnms.so'
报错,可在app->build.gradle
中添加1
2
3
4
5
6
7
8
9android {
...
// Fix: More than one file was found
packagingOptions {
pickFirst 'lib/armeabi-v7a/libnms.so'
}
}
关于so版本选择
armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它
arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一
armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多
x86: 平板、模拟器用得比较多
x86_64: 64位的平板