本文采用的是NDK+LLDB的方式(虽然CMake方式比较流行,但是要考虑历史惯性啊)
Android Studio 的安装不说了。
查看和安装NDK和LLDB:
Android Studio -> Preferences -> Appearance & Behavior -> System Settings -> Android SDK -> SDK Tools
GmSSL.C
是GmSSL.java
的Native实现,因为关联的文件相对简单,所以调试起来也比较容易。
1、
编译libssl.so
和libcrypto.so
(编译过程,https://blog.csdn.net/holdsky/article/details/89213537 )
需要注意的是,我们需要编译出SONAME
为libxxx_1_1.so
形式的so库,以解决Android低版本(Android 4和5)适配兼容问题。
将生成的libssl.so.1.1
和libcrypto.so.1.1
分别命名为libssl_1_1.so
和libcrypto_1_1.so
(文件名需要和SONAME
保持一致)
同时,GmSSL.java中的加载so代码变为
static {
System.loadLibrary("crypto_1_1");
System.loadLibrary("ssl_1_1");
System.loadLibrary("gmssljni");
}
2、
用Android Studio 新建一个Android空白工程,作为调试Native的宿主用。
3、
复制文件
在Android工程的src/main
目录下,创建目录jni/gmsslNative
把GmSSL源码目录的include
、java
、e_os.h
文件和文件夹复制到jni/gmsslNative
中
把1步骤生成的libssl_1_1.so
和libcrypto_1_1.so
复制到gmsslNative/java
中
把gmsslNative/java
中的GmSSL.java
移动到src/main/java
下某个目录中
4、
打开AndroidManifest.xml
文件,在application
节点添加属性android:debuggable="true"
application>
配置build.gradle,在defaultConfig
添加NDK配置
android {
defaultConfig {
ndk {
moduleName "gmssljni"
abiFilters "armeabi-v7a"//编译支持指令集
}
}
externalNativeBuild {
ndkBuild {
// Android.mk 的相对路径
path "src/main/jni/gmsslNative/java/Android.mk"
}
}
}
5、
配置Android.mk
Application.mk
,并把文件放在gmsslNative/java
中(这个路径和build.gradle
中externalNativeBuild
要保持一致)
Android.mk
# Android.mk
#宏函数 my-dir 将返回当前目录(Android.mk 文件本身所在的目录)的路径。
LOCAL_PATH := $(call my-dir)
# libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := libcrypto_1_1.so
include $(PREBUILT_SHARED_LIBRARY)
#libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := libssl_1_1.so
include $(PREBUILT_SHARED_LIBRARY)
#libgmssljni
include $(CLEAR_VARS)
# CPU 系列 arm arm64 x86 x86_64
TARGET_ARCH := arm
# Android API 级别号
TARGET_PLATFORM := android-18
#模块的名称 生成最终共享库文件名为 lib模块名字.so
LOCAL_MODULE := gmssljni
#头文件搜索路径
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
#源文件 (以空格分隔多个文件)
LOCAL_SRC_FILES := gmssl_err.c GmSSL.c
#需要连接的动态库
LOCAL_SHARED_LIBRARIES := crypto ssl
#帮助系统将所有内容连接到一起
include $(BUILD_SHARED_LIBRARY)
Application.mk
#Android 版本 最小支持为android-16
APP_PLATFORM := android-18
#指令集
APP_ABI := armeabi-v7a
6、
因为GmSSL.java文件中没有包名,所以不能调用GmSSL.java中的方法。
要解决这个问题,可以利用java的反射机制,也可以在GmSSL.c中指定包名,具体不赘述。
打开GmSSL.c 文件,找个地方打个断点,例如在JNI_OnLoad
方法中,然后连上手机,点击Android Studio的Debug按钮,等待等待等待等待等待
过程和调试libgmssl.so基本差不多,各种配置也基本一样,不同的地方为:
A、编译libcrypto_1_1.so和libssl_1_1.so时,需要打开Makefile
文件,搜索-o3
,替换成-g
这样,生成的so库是带有调试信息的。
B、现在libgmssl中打个断点,当断点到达时,在Android Studio的调试控制台的LLDB窗口中输入命令add-dsym xxx.so
add-dysm xxx/app/src/main/jni/gmsslNative/java/libssl_1_1.so #这个so是A步骤的so
add-dysm xxx/app/src/main/jni/gmsslNative/java/libcrypto_1_1.so #这个so是A步骤的so