环境说明
- 本人所用Android Studio版本号为3.0.1,稳定耐用为防坑不做升级
- Windows10系统
具体步骤
1、下载NDK工具
可分为两种方式,Android studio自动下载和手动官网下载解压
方式一,点击Android studio导航栏File——》Project Structure,如下图所示
下载完成后会自动配置Android NDK location,复制此路径在系统高级环境变量中进行设置,这里不做累述,记得在Path变量中添加 %NDK路径%,命令行输入ndk-build,输出以下即为变量配置成功
方式二,前往NDK官网下载想要的版本,个人建议选择最右侧的旧版本,最新的NDK版本更能兼容最新的Android studio版本和最新的Gradle版本,否则会有些莫名其妙的问题,例如本人遇见的No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android问题,如遇相同问题,可以手动下载配置历史版本Rebuild Project
2、配置javah及ndk-build快速构建工具
具体参数如下
Program:D:\Android\Sdk\ndk-bundle\ndk-build.cmd(注意路径是ndk加上ndk-build.cmd)
Working directore:$ModuleFileDir$\src\main
点击保存接着配置javah
参数如下
Program:$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$/src/main/jni $FileClass$
Working directore:$ModuleFileDir$\src\main\java
点击保存就会在Setting——Tools——External Tools中生成两个快速命令行编译工具
3、新建java文件,使用调用C代码的语法格式
接着右键点击文件选择 External Tools——javah就会自动生成jni文件夹下的对应头文件。
复制生成的.h 文件拷贝到同文件夹下,并把文件后缀改成.c,文件名字可以保持和 .h 文件同名,也可以如上图所示自定义文件名,.c文件内写入的就是各个JNI函数的具体C语言实现,可能得和C工程师合作编写,这里不做探讨,需要注意的是 .c文件内需要引入.h头文件,即添加这一句
在jni文件夹下新建Android.mk文件,写入以下
记得改动图中圈红的地方
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hhjni_ledclass
LOCAL_SRC_FILES := hhjni_ledclass.c
LOCAL_CFLAGS := -Werror
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)
继续新建Application.mk文件,写入以下内容便于生成对应的so文件,一般一个armeabi-v7指令集限制足矣
APP_ABI := armeabi armeabi-v7a arm64-v8a
至于.cpp文件,可加可不加,加的就是自定义文件名.cpp,只用写入一句话
#include <jni.h>
此时所有JNI文件编写完成,接下来就是通过NDK工具编译成so文件,右键点击jni文件夹,选择External Tools——ndk-build,编译顺利就会在控制台打印出如下日志
这时libs文件夹下就会自动生成对应指令集下的so文件,选择你需要的so文件以及开始创建的.java文件拷贝到项目中就可以愉快的开始使用Java代码调用C++代码了
问题记录
- 本人使用ndk-build工具编译时遇见如下报错
jni/hhjni_ledclass.c:47:2: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
ioctl(ledfd, HDMI_ON);
^
1 error generated.
make: *** [obj/local/armeabi-v7a/objs/hhjni_ledclass/hhjni_ledclass.o] Error 1
网上耐心查询了一番终于找到解决方法,在.c文件内添加显式的声明头文件
#include <unistd.h> //for read close
#include <sys/stat.h> //for mkfifo
#include<fcntl.h> //for open
然后重新编译即可
- 报错Android NDK: Application targets deprecated ABI(s): armeabi
- 移除Application.mk文件内的armeabi指令集即可