alipaysdk-15.8.06 拆分 jar 包后无法调起 H5 支付
结论
不建议把 alipaysdk-15.8.06.aar 直接拆成单独的 JAR 使用。
AAR 中不只有 Java 字节码,还可能包含:
AndroidManifest.xml中声明的组件、权限或配置consumer-rules.pro、proguard.txt等消费者混淆规则res/资源assets/jni/下的 native library- 其他元数据
如果拆分后只引用 classes.jar,这些内容不会自动合并到宿主应用中。代码即使能够编译,运行时仍可能因为类被删除或改名、组件未注册、资源缺失等问题,导致 H5 支付页面无法调起。
在没有对应版本官方集成说明的情况下,无法确认 alipaysdk-15.8.06 是否仍支持只使用 JAR 的接入方式。更稳妥的做法是继续使用原始 AAR。如果项目必须使用 JAR,就需要逐项迁移 AAR 中除 classes.jar 之外的必要内容,不能只处理混淆规则。
为什么 AAR 正常,JAR 不正常
Android Gradle Plugin 处理 AAR 依赖时,会合并其中的 Manifest、资源和消费者混淆规则。换成本地 JAR 后,Gradle 通常只处理 JAR 中的 class 文件,不会自动继承原 AAR 的其他配置。
如果问题只在开启 minifyEnabled 后出现,关闭混淆就能恢复,通常至少涉及以下一种情况:
- 通过反射访问的类或成员被 R8 删除或改名;
- JavaScript Bridge 使用的方法被优化;
- WebView 相关回调类被裁剪;
- SDK 依赖的注解、内部类或序列化字段没有保留;
- AAR 自带的消费者混淆规则在拆分时丢失。
如果关闭混淆后仍然无法调起,就不能只排查 ProGuard/R8,还要确认 Manifest、资源和 native library 是否完整迁移。
推荐方案:直接保留 AAR
将 AAR 放入模块的 libs 目录:
app/
├── libs/
│ └── alipaysdk-15.8.06.aar
└── build.gradle
Groovy DSL 可以这样声明:
dependencies {
implementation files('libs/alipaysdk-15.8.06.aar')
}
有些工程也会使用 flatDir:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation(name: 'alipaysdk-15.8.06', ext: 'aar')
}
如果 Gradle 版本允许,建议优先使用直接文件依赖,以免受到 flatDir 无法利用标准模块元数据的影响。
必须拆成 JAR 时的处理方式
1. 先检查 AAR 的实际内容
AAR 本质上是 ZIP 文件,可以用下面的命令列出其中的文件:
unzip -l alipaysdk-15.8.06.aar
重点检查这些内容:
classes.jar
AndroidManifest.xml
consumer-rules.pro
proguard.txt
res/
assets/
jni/
libs/
不同 AAR 的混淆规则文件名可能不同,应以包内的实际内容为准,不要默认其中一定有 consumer-rules.pro。
2. 迁移原有消费者混淆规则
如果 AAR 中包含混淆文件,应将其解压到宿主模块,例如:
app/
├── libs/
│ └── alipaysdk-15.8.06.jar
├── proguard/
│ └── alipaysdk-consumer-rules.pro
└── build.gradle
然后在应用模块中引用:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro',
'proguard/alipaysdk-consumer-rules.pro'
}
}
}
普通本地 JAR 无法可靠地替代 AAR 的消费者规则传递机制。比较直接的做法,是在最终执行 R8/ProGuard 的应用模块中显式加入原规则。
不要只是把 -keep 配置放进 JAR,然后期待 Gradle 自动读取。构建工具链是否识别 JAR 内的特定元数据路径并不确定,兼容性也不如 AAR。
3. 没有原始规则时,先用保守规则定位
如果包内确实没有消费者规则,可以先用较为保守的配置验证问题是否由混淆引起。下面的包名只是示例,必须按照 JAR 中的真实类名调整:
-keep class com.alipay.** { *; }
-keep interface com.alipay.** { *; }
-dontwarn com.alipay.**
这类规则适合用来定位问题,但不建议在没有分析的情况下长期使用,因为保留范围可能过大。
确认功能恢复后,可以根据 R8 输出逐步缩小规则范围。例如,重点保留:
-keepclasseswithmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepattributes *Annotation*
-keepattributes InnerClasses
-keepattributes EnclosingMethod
-keepattributes Signature
不要凭经验编写针对某个支付宝 SDK 内部类的精确规则。不同版本的包结构和实现可能不同,应以 alipaysdk-15.8.06 中实际包含的类、原 AAR 规则和运行日志为准。
4. 检查 Manifest 是否丢失
对比原 AAR 的 Manifest 和最终合并后的 Manifest,确认相关组件及配置是否仍然存在。
最终合并结果通常可以在 Android Studio 的 Merged Manifest 页面查看,也可以检查构建目录中的合并产物。需要重点关注:
activityserviceprovideruses-permissionqueriesmeta-data
如果 AAR 声明了相关组件,改用 JAR 后,需要在宿主应用的 AndroidManifest.xml 中手动补齐。具体内容应从原 AAR 的 Manifest 中提取,不要照搬网上其他 SDK 版本的示例。
5. 迁移资源和 native library
如果 AAR 中包含 res/,单独引用 JAR 不会带上这些资源,需要将其合并到 Android Library 模块或应用模块中。
如果包含:
jni/armeabi-v7a/
jni/arm64-v8a/
jni/x86/
jni/x86_64/
还必须把对应的 .so 文件放入模块的 src/main/jniLibs/,例如:
app/src/main/jniLibs/arm64-v8a/libxxx.so
同时检查项目中的 abiFilters,避免在构建时排除所需的 ABI。
更合适的兼容方案:包装成内部 AAR
如果上层工程要求按拆分后的依赖管理 SDK,可以新建一个 Android Library 模块,把 JAR、Manifest、资源和 native library 放入其中,最后重新生成内部 AAR。
模块配置示例:
plugins {
id 'com.android.library'
}
android {
namespace 'com.example.alipay.wrapper'
defaultConfig {
consumerProguardFiles 'consumer-rules.pro'
}
}
dependencies {
implementation files('libs/alipaysdk-15.8.06.jar')
}
目录可以这样组织:
alipay-wrapper/
├── libs/
│ └── alipaysdk-15.8.06.jar
├── src/main/
│ ├── AndroidManifest.xml
│ ├── res/
│ ├── assets/
│ └── jniLibs/
├── consumer-rules.pro
└── build.gradle
这种方案最终交付的仍是 AAR,但既能满足内部依赖治理要求,也能继续传递 Manifest、资源和消费者混淆规则。
如何确认是否确实由混淆引起
可以按以下顺序排查:
- 保持 JAR 集成方式不变,临时将
minifyEnabled设为false。 - 如果 H5 支付恢复,重点检查原 AAR 的混淆规则,以及 R8 对相关类的删除和改名结果。
- 如果仍然失败,检查合并后的 Manifest、资源、
.so文件和 SDK 依赖。 - 对比 debug 与 release 的 Logcat,留意
ClassNotFoundException、NoSuchMethodException、ActivityNotFoundException、UnsatisfiedLinkError和 WebView JavaScript 调用异常。 - 查看 R8 生成的
mapping.txt、usage.txt和seeds.txt,确认相关类是否被改名或移除。
仅凭 “AAR 正常、JAR 异常” 还不能断定问题一定出在混淆。对比关闭混淆后的运行结果,是判断排查方向最有效的一步。
注意事项
- 不要只复制 AAR 中的
classes.jar,再把文件改名为 SDK JAR。这不等于完整迁移。 -dontwarn只能隐藏警告,无法阻止类被删除或改名,也不能修复运行时缺少组件的问题。- 支付 SDK 涉及安全逻辑,不建议对其字节码进行二次打包、修改或重新混淆。
- 如果拆分包来自第三方渠道,应优先换成官方发布的完整依赖。
- 如果业务必须使用纯 JAR,建议向 SDK 提供方确认该版本是否有正式的 JAR 接入包及配套规则。自行从 AAR 中拆出的 JAR,不应视为官方支持的交付形式。
备注:内容仅供参考。
