準備工作
- 由於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++項目