生成so文件之静态注册

Android开发中,我们经常会用到.so文件。原因有很多,比如部分方法不想暴露,如加密规则。比如部分秘钥需要存储,哪怕最简单的一个加盐的String。我们使用.so调用获取这个String,也比直接明文写在代码中要来的安全。所以就需要我们安卓开发的同学,要知道简单的.so怎么编写。今天为大家带来一篇,如何通过Native方法,从.so中获取一个字符串(可以存储秘钥哦)。

这个我生成so文件时studio 的版本

生成so文件之静态注册_第1张图片

1、首先是要配置NDK(若是已经配置过NDK请略过此步骤)

官网下载NDK地址(此地址下载需要翻墙)

若是你翻不了墙请移步至

一个强大的下载网站(Androiddevtools你值得拥有)  https://www.androiddevtools.cn/

下载好之后是个压缩包,应该做什么你应该知道了,然后下面进行第二步

Android Studio下载的是最新版——NDK14。顺便连CMake和LLDB也下载了。

CMake: C/C++的外部构建工具,可以提示代码什么的。

LLDB: 调试本地代码的工具。


生成so文件之静态注册_第2张图片

2、配置环境变量

创建NDK_HOME

再将配置好的NDK_HOME添加到PATH环境变量中

配置好之后可以测试是否配置正确 ,打开cmd在里面输入ndk-build

出现上述结果就说明ndk环境变量已经设置成功了,提示信息是因为没有定义NDK_PROJECT_PATH变量,此处用不到,我们暂不处理

3、开始对Android Studio进行NDK环境配置


生成so文件之静态注册_第3张图片
生成so文件之静态注册_第4张图片

4.下一步是编写我们的Native方法   创建一个NativeUtils类,以实现jni调用


生成so文件之静态注册_第5张图片

然后clean project 再rebuild project 生成class文件,这时候打开如下图的文件夹看是否生成了classes文件夹,没有生成请重新来过。

生成so文件之静态注册_第6张图片

这里生成的文件路径,是 app/build/intermediates/classes/debug/包名.../NativeUtils.class

也有可能生成的是别的路径:app/build/intermediates/javac/debug/compileDebugJavawithJavac/classes/包名.../NativeUtils.class

以上两种都是我在不同项目中遇到的。也有可能是别的路径。

5.下一步:


生成so文件之静态注册_第7张图片

接下去在termianl窗口中执行javah -classpath . -jni 包名.文件名

javah -classpath . -jni adbdeom.wyh.com.myadb.class_so.NativeUtils

生成so文件之静态注册_第8张图片


生成so文件之静态注册_第9张图片


生成so文件之静态注册_第10张图片


生成so文件之静态注册_第11张图片


生成so文件之静态注册_第12张图片

6.接下来我们要在jni目录下创建Android.mk和Application.mk文件

Android.mk文件内容为


生成so文件之静态注册_第13张图片

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := aaajni

LOCAL_SRC_FILES := test.c

include $(BUILD_SHARED_LIBRARY)

Application.mk内容为(这个配置是为了生成所有平台的so库,若不配置只会生成armeabi目录下的)


生成so文件之静态注册_第14张图片

APP_ABI := all


生成so文件之静态注册_第15张图片


生成so文件之静态注册_第16张图片

其中ndk标签是新添加的,moduleName 的值同样为System.loadLibrary("aaajni");的参数。由于配置了abiFilters,则只会得到armeabi、x86、armeabi-v7a三种ABI对应的.so文件。

7.

生成so文件之静态注册_第17张图片

执行了ndk-build 成功后  自动生成了libs,obj两个文件夹。

生成so文件之静态注册_第18张图片

总结:  生成完了.so 那么对应的jni里面的c代码就不需要了。你可以删除,可以保存到别的地方。总之,你开心就好。

可以把生成.so文件 过程中 jni,libs,obj上文件 拿掉。

生成so文件之静态注册_第19张图片

最后运行结果如下:

TextView tv = findViewById(R.id.text);

tv.setText(new NativeUtils().getStringKey());


生成so文件之静态注册_第20张图片

这出现的问题1:

生成so文件之静态注册_第21张图片


重启下项目 解决


问题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还需要配置

生成so文件之静态注册_第22张图片


生成so文件之静态注册_第23张图片

sourceSets {

main {

jniLibs.srcDirs = ['src/jniLibs']

jni.srcDirs = []

}

}

这段主要放置的位置,需放在buildTypes下。jni.srcDirs = []不能删,去掉会报另一个错误。如下图:


生成so文件之静态注册_第24张图片

你可能感兴趣的