用AndroidStudio编写第一个so

so就像Windows中的dll文件,是二进制程序,只保留调用接口。用C/C++实现

Android开发中,我们经常会用到.so文件。原因有很多,比如部分方法不想暴露,如加密规则。比如部分秘钥需要存储,哪怕最简单的一个String我们使用.so调用获取这个String,也比直接明文写在代码中要来的安全。

关于NDK与JNI的资料:https://www.jianshu.com/p/87ce6f565d37

步骤

吾爱破解上虽然是2018年的教程,但是Android studio和Java实在更新太快,很多步骤不再适用,踩了很多坑。下面将复现使用AS编写so并调用,顺便完成课后作业。

编写so并在里面实现一个加法的功能
最终效果:java层调用so中的Add方法,传入两个参数22和30,通过log显示出来52

新建项目,新建一个Java类声明native方法

image-20210201113022626

生成.h头文件

在app/src/main文件夹下新建一个jni文件夹,然后打开Android Studio的终端,cd到这个目录

1
2
D:\GitHub\AndroidStudioProjects\secondso\app\src\main\jni>javac -h . D:\GitHub\AndroidStudioProjects\secondso\app\src\main\java\com\luc
kyfuture\secondso\MysecondJni.java

Java新版本用Javac -h代替了Javah,其实并不用上一步生成.class文件,可直接对.java进行编译

会在这个jni文件夹下生成一个.h文件

image-20210201114831206

在jni目录下新建一个c/c++source file ,实现上面.h文件中的方法

image-20210201120000427

这里因为对JNI不熟悉,代码写的不对。详细资料:https://www.cnblogs.com/qixingchao/p/11911787.html

在jni文件夹下新建Android.mk和Application.mk文件

Android.mk

1
2
3
4
5
6
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := MysecondJni
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)

Application.mk

1
APP_ABI := all

关联下载好的ndk包

image-20210201115711734

下载地址 https://developer.android.com/ndk/downloads/index.html

进入到jni目录,输入指令 ndk-build,生成相应的so文件

image-20210201123335057

调用so文件

在app的bulid文件中加入如下代码,然后build project

image-20210201120318216

在mainactivity中调用so方法

image-20210201121621582

调用so方法成功

踩坑记录

javah : 无法将“javah”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次

如果你环境变量已加好,各种方法都试过,还是出现上述问题,那很可能是用的jdk版本比较高。
新版JDK已经用javac -h 来代替javah

The option ‘android.useDeprecatedNdk’ is deprecated.

这条提醒简直就是在套娃。新版本中ndk支持使用cmake和ndk-build实现,具体参考例子中的步骤。

logcat read: unexpected EOF!

运行之后之后logcat一直显示这个没反应,原因是logcat缓存爆了。在logcat中右键clear logcat就好了

参考资料:

https://blog.csdn.net/leilifengxingmw/article/details/71598687

https://www.52pojie.cn/thread-706568-1-1.html