准备工作
- 由于ndk版本和IDE的版本可能存在不一致性,所以编译时会检查ndk的过时性,这个时候如果报警了,可以在gradle.properties文件下添加一行:
## 随着gradle版本的升级,这条设置被废弃了,也就是说高版本gradle里就算设置了下面这句,也会被移除
android.useDeprecatedNdk=true
- 配置环境变量,方便通过命令提示行,在任意地方使用ndk命令
linux不用配置环境,Windows需要在环境变量里找到Paht,添加ndk根目录地址路径。ndk下到哪,使用哪个版本,自己配。举个例子我就使用Android Studio下的,路径为 D:\Android\Sdk\ndk-bundle,我就把她添加进Path。 - 对于习惯使用Android Studio来编译so的,需要在local.properties设置ndk路径
ndk.dir=D\:\\Android\\Sdk\\ndk-bundle
通过ndk-build命令生成so
这种方法适用于修改打过so库的项目,比如之前我有用过一个zbar编译的so库,但是他库文件缺少对arm64-v8a架构机器的支持,所以我自己在GitHub找到项目之后,重新编译了一遍。
使用命令提示窗口或者Android Studio的Terminal提示框,切换目录到要编译的目录。这种目录一般带有Android.mk和Application.mk文件。确认一下Application.mk指定需要的so文件架构类型,再确认下Android.mk里引用,so名称,路径等设置。没有问题之后键入命令:
ndk-build
例子
# Application.mk
APP_ABI := all
# Android.mk
LOCAL_PATH := $(call my-dir)
#APP_PATH:= $(NDK)/$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libiconv
LIBICONV := libiconv
LOCAL_CFLAGS := -I$(LOCAL_PATH)/$(LIBICONV)
LOCAL_SRC_FILES := $(LIBICONV)/iconv.c
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ZBarDecoder
LOCAL_SRC_FILES := convert.c \
decoder.c \
error.c \
image.c \
img_scanner.c \
refcnt.c \
scanner.c \
symbol.c \
video.c \
window.c \
qrcode/bch15_5.c \
qrcode/binarize.c \
qrcode/isaac.c \
qrcode/qrdec.c \
qrcode/qrdectxt.c \
qrcode/rs.c \
qrcode/util.c \
processor/null.c \
video/null.c \
window/null.c \
decoder/qr_finder.c \
decoder/code128.c \
decoder/code39.c \
decoder/code93.c \
decoder/codabar.c \
decoder/ean.c \
decoder/databar.c \
decoder/i25.c \
com_dtr_zbar_build_ZBarDecoder.c
LOCAL_CFLAGS := -I$(LOCAL_PATH) -I$(LOCAL_PATH)/$(LIBICONV)
LOCAL_LDLIBS := -llog
LOCAL_STATIC_LIBRARIES := libiconv
include $(BUILD_SHARED_LIBRARY)
编译完之后生成了2个文件夹libs和obj,看看libs里有啥
里面的so文件,叫做libZBarDecoder.so,使用的时候使用System.loadLibrary("ZBarDecoder");就完事了。
时代在变化,其实很多架构的手机已经逐渐淡出市场了,如果还是编译全部的话,可能有点浪费时间,只需要修改Application.mk:
APP_ABI := armeabi-v7a arm64-v8a
如需了解mk文件语法请参考官方文档:Android.mk 和 Application.mk
使用CMake
生成so文件的关键在于CMakeLists.txt文件,可以把它看成一个脚本。一般指定某个CMakeLists.txt后,编译都能产生so。
具体可以查看我之前写过的JNI使用记录-Android Studio创建Native C++项目