Android Studio 2.3.1
FrankNote: Android 3.1.2
1. 新建New Project:
2. 自動打開新建的工程:
a) 以project的方式顯示工程:
b) Main目錄下新建jni文件夾:
FrankNote: 如果之前沒有安裝NDK, 自動下載NDK, 退出,重新打開Android Studio 就可以看到下圖所示的項目
c) jni文件夾下新建test_hello_world.cpp:
d) jni文件夾下新建Android.mk:
FrankNote:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE LOCAL_MODULE := test_hello_world LOCAL_SRC_FILES =: test_hello_world.cpp include $(BUILD_EXECUTABLE)
LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE
原因 PIE這個安全機制從4.1引入,但是Android L之前的系統版本並不會去檢驗可執行文件是否基於PIE編譯出的。因此不會報錯。但是Android L已經開啟驗證,如果調用的可執行文件不是基於PIE方式編譯的,則無法運行。解決辦法非常簡單,在Android.mk中加入如下flag就行。
https://blog.csdn.net/hxdanya/article/details/39371759
FrankNote End
e) jni文件夾下新建Application.mk文件,作用在於支持c++共享庫:
FrankNote:
APP_STL := gnustl_static
原因:
原方案使用的是共享庫,這不一定都支持所有的機型,改用靜態庫gnustl_static 問題解決。
https://blog.csdn.net/luozhuang/article/details/36418229
f) 注意觀察project下的local.properties文件:
g) 修改project下的gradle.properties文件,增加配置android.useDeprecatedNdk=true,其作用在於告訴系統使用ndk編譯:
h) 修改app目錄下的build.gradle文件,增加配置:
i. ndk的abiFilters配置作用在於限定生成的cpu/abi。
ii. jni.srcDirs = [] 表示禁止as自動ndk編譯,采用手動ndk-build。
iii. jniLibs.srcDirs = [‘src/main/libs’] 表示經過ndk-build編譯后的so路徑。
i) jni文件夾下新建Cmd script,make_x86.cmd,用於手動ndk-build:
j) 右鍵點擊make_x86.cmd文件選擇Run cmd script:
k) 獲得目標程序文件test_hello_world:
C:\Users\jacki\AppData\Local\Android\Sdk\ndk-bundle\ndk-build.cmd APP_ABI="x86"
3. 在Android虛擬機中執行程序:
a) 開啟x86 cpu/abi的虛擬機:
b) 使用adb命令把文件傳到Android虛擬機中,並賦予可執行權限:
靜態庫沒有.so文件
c) 添加當前路徑為so庫文件查找路徑命令,防止elf文件運行階段找不到so庫的問題,LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp