Android开发中,我们经常会用到.so文件。原因有很多,比如部分方法不想暴露,如加密规则。比如部分秘钥需要存储,哪怕最简单的一个加盐的String。我们使用.so调用获取这个String,也比直接明文写在代码中要来的安全。所以就需要我们安卓开发的同学,要知道简单的.so怎么编写。今天为大家带来一篇,如何通过Native方法,从.so中获取一个字符串(可以存储秘钥哦)。
这个我生成so文件时studio 的版本
1、首先是要配置NDK(若是已经配置过NDK请略过此步骤)
官网下载NDK地址(此地址下载需要翻墙)
若是你翻不了墙请移步至
一个强大的下载网站(Androiddevtools你值得拥有) https://www.androiddevtools.cn/
下载好之后是个压缩包,应该做什么你应该知道了,然后下面进行第二步
Android Studio下载的是最新版——NDK14。顺便连CMake和LLDB也下载了。
CMake: C/C++的外部构建工具,可以提示代码什么的。
LLDB: 调试本地代码的工具。
2、配置环境变量
创建NDK_HOME
![](http://img.e-com-net.com/image/info10/6574e8ff49ad410cb4d1def7bb89ceb1.jpg)
再将配置好的NDK_HOME添加到PATH环境变量中
![](http://img.e-com-net.com/image/info10/c58a128157824750ab9a319e83d368f9.jpg)
配置好之后可以测试是否配置正确 ,打开cmd在里面输入ndk-build
![](http://img.e-com-net.com/image/info10/6a784e8414f24755b83c504cdbc0bcaf.png)
出现上述结果就说明ndk环境变量已经设置成功了,提示信息是因为没有定义NDK_PROJECT_PATH变量,此处用不到,我们暂不处理
3、开始对Android Studio进行NDK环境配置
4.下一步是编写我们的Native方法 创建一个NativeUtils类,以实现jni调用
然后clean project 再rebuild project 生成class文件,这时候打开如下图的文件夹看是否生成了classes文件夹,没有生成请重新来过。
这里生成的文件路径,是 app/build/intermediates/classes/debug/包名.../NativeUtils.class
也有可能生成的是别的路径:app/build/intermediates/javac/debug/compileDebugJavawithJavac/classes/包名.../NativeUtils.class
以上两种都是我在不同项目中遇到的。也有可能是别的路径。
5.下一步:
接下去在termianl窗口中执行javah -classpath . -jni 包名.文件名
javah -classpath . -jni adbdeom.wyh.com.myadb.class_so.NativeUtils
6.接下来我们要在jni目录下创建Android.mk和Application.mk文件
Android.mk文件内容为
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := aaajni
LOCAL_SRC_FILES := test.c
include $(BUILD_SHARED_LIBRARY)
Application.mk内容为(这个配置是为了生成所有平台的so库,若不配置只会生成armeabi目录下的)
APP_ABI := all
其中ndk标签是新添加的,moduleName 的值同样为System.loadLibrary("aaajni");的参数。由于配置了abiFilters,则只会得到armeabi、x86、armeabi-v7a三种ABI对应的.so文件。
7.
执行了ndk-build 成功后 自动生成了libs,obj两个文件夹。
总结: 生成完了.so 那么对应的jni里面的c代码就不需要了。你可以删除,可以保存到别的地方。总之,你开心就好。
可以把生成.so文件 过程中 jni,libs,obj上文件 拿掉。
最后运行结果如下:
TextView tv = findViewById(R.id.text);
tv.setText(new NativeUtils().getStringKey());
这出现的问题1:
重启下项目 解决
问题2:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/adbdeom.wyh.com.myadb-1/base.apk"],nativeLibraryDirectories=[/data/app/adbdeom.wyh.com.myadb-1/lib/arm64, /system/lib64, /vendor/lib64]]] couldn't find "libaaajni.so"
解决:
在src文件夹下创建jniLibs文件夹,并把之前生的相关so文件,放进去。同时app目录下的build.gradle还需要配置
sourceSets {
main {
jniLibs.srcDirs = ['src/jniLibs']
jni.srcDirs = []
}
}
这段主要放置的位置,需放在buildTypes下。jni.srcDirs = []不能删,去掉会报另一个错误。如下图: