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:UsersjackiAppDataLocalAndroidSdk
dk-bundle
dk-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