生成so文件之静态注册

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

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

6188765-151c6ff3fd9bff96.png

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

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

若是你翻不了墙请移步至

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

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

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

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

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


6188765-6103a9ce24b46058.png

2、配置环境变量

创建NDK_HOME

1084254-767b88e586e73900.png

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

1084254-51214b696a975dc6.png

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

1084254-87f73ec3143e68c9.png

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

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


6188765-226ba288f2f1eecb.png
6188765-5c4c60c094126917.png

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


6188765-93ffa28476393ea1.png

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

6188765-bc579ed35aca668c.png

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

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

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

5.下一步:


6188765-b7635c2b6de98a4d.png

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

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

6188765-c12c0000b1b0983b.png


6188765-e5f9ad4c710a2938.png


6188765-a5696c36b7326fd2.png


6188765-eceaa59fb5cd5f6f.png


6188765-93bbd69217534b51.png

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

Android.mk文件内容为


6188765-077e62c46846859c.png

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := aaajni

LOCAL_SRC_FILES := test.c

include $(BUILD_SHARED_LIBRARY)

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


6188765-c9a7fa837fef1e56.png

APP_ABI := all


6188765-b33def1c0a033ac7.png


6188765-4152f910357cc9ac.png

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

7.

6188765-0519f730c114f58c.png

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

6188765-029a00f5f9deaea0.png

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

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

6188765-982b7cf188580e31.png

最后运行结果如下:

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

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


6188765-29e1d95fb3504ea6.png

这出现的问题1:

6188765-dd8b0eb7e5490f9c.png


6188765-2dcd61bd0df51b02.png

重启下项目 解决


问题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"

6188765-c5d18e26b9fc3530.png

解决:

在src文件夹下创建jniLibs文件夹,并把之前生的相关so文件,放进去。同时app目录下的build.gradle还需要配置

6188765-42f46954064e639a.png


6188765-afe0c696b72fbed4.png

sourceSets {

main {

jniLibs.srcDirs = ['src/jniLibs']

jni.srcDirs = []

}

}

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


6188765-39562cc02dc04693.png

猜你喜欢

转载自blog.csdn.net/weixin_33888907/article/details/86815535