U3D 接入支付宝支付时调用闪退并提示 PayTask 类缺失
结论
这个报错的直接原因是:应用运行时的 DEX 中没有 com.alipay.sdk.app.PayTask。
问题通常不在支付调用代码本身,而是支付宝客户端 SDK 的 AAR/JAR 没有被 Unity 正确打入 APK/AAB,或者在 Gradle 配置、依赖冲突、代码压缩等环节被遗漏。
建议先检查支付宝 SDK 是否正确放在 Assets/Plugins/Android 中,再确认最终安装包里是否真的包含 PayTask。
原因分析
日志中的关键信息如下:
java.lang.NoClassDefFoundError: Failed resolution of:
Lcom/alipay/sdk/app/PayTask;
Caused by: java.lang.ClassNotFoundException:
com.alipay.sdk.app.PayTask
代码在编译时可以引用 PayTask,但运行到 MainActivity.java:161 时,Android 类加载器找不到这个类。
常见原因有:
- 支付宝 SDK 的
.aar或.jar文件没有放进 Unity 的 Android 插件目录。 - 插件文件虽然存在,但没有在 Inspector 中启用 Android 平台。
- 自定义 Gradle 模板没有声明支付宝 SDK 依赖。
- 导出 Android Studio 工程后,依赖被添加到了错误的 Module。
- 使用依赖管理插件后,没有执行依赖解析。
- 工程中同时存在多个版本的支付宝 SDK,引发依赖冲突或打包异常。
- Release 包启用了 R8/ProGuard,相关类被错误裁剪。
- Unity 构建缓存还在使用旧的 Gradle 工程或旧插件。
这不是 .so 架构缺失导致的问题。ABI 不匹配通常会触发 UnsatisfiedLinkError,当前日志指向的是 Java 类缺失。
排查步骤
1. 检查支付宝 SDK 文件
如果使用本地 AAR,请确认目录中存在类似文件:
Assets/
└── Plugins/
└── Android/
└── alipay-sdk.aar
具体文件名取决于所用的支付宝 SDK,不一定叫 alipay-sdk.aar。
在 Unity 中选中该文件,检查 Plugin Inspector:
- Android 平台已经启用。
- 没有只勾选 Editor、iOS 等无关平台。
- Android 没有被错误的平台过滤规则排除。
- 工程中没有另一个旧版本的支付宝 SDK。
如果拿到的是完整的支付宝 SDK 包,应按照对应版本的接入说明导入,不能只复制示例工程中的 Java 调用代码。
2. 检查 Gradle 依赖
如果 AAR 位于 Android Module 的 libs 目录,可以使用本地依赖:
dependencies {
implementation files('libs/alipay-sdk.aar')
}
也可以匹配该目录中的所有 AAR:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
如果使用 Maven 依赖,应填写支付宝当前接入文档提供的坐标,例如:
dependencies {
implementation '支付宝文档指定的 groupId:artifactId:version'
}
不要随意填写版本号。支付宝 SDK 的发布渠道和版本不同,依赖坐标也可能不同,应以实际下载包或对应版本的官方接入说明为准。
Unity 启用自定义 Gradle 模板后,还要确认依赖被写入了实际参与构建的 Module。不同 Unity 版本和导出方式可能使用 launcher、unityLibrary 或其他 Module。不能只检查模板文件是否存在,还要查看最终生成的 build.gradle。
3. 检查导出的 Android Studio 工程
如果先从 Unity 导出工程,再通过 Android Studio 打包,需要确认:
- 支付宝 SDK 位于实际运行 Module 的依赖链中。
- Gradle Sync 没有报错。
dependencies中可以看到支付宝 SDK。- 导出后没有删除
libs目录或覆盖build.gradle。 debugImplementation、releaseImplementation等配置没有导致依赖只对某一种构建类型生效。
可以执行:
./gradlew app:dependencies
实际的 Module 名称不一定是 app。如果工程使用 launcher,可能需要执行:
./gradlew launcher:dependencies
在输出中查找支付宝 SDK,确认它已经进入对应构建变体的依赖树。
4. 检查最终 APK
项目目录里存在 AAR,并不代表它一定进入了安装包,还需要直接检查最终 APK。
可以使用 Android Studio 的 Build > Analyze APK 打开 APK,然后查看 DEX 中是否存在:
com.alipay.sdk.app.PayTask
也可以使用 Android SDK Build Tools 中的 apkanalyzer:
apkanalyzer dex packages --defined-only app-release.apk
再在输出中查找:
com.alipay.sdk.app.PayTask
如果 APK 中找不到这个类,问题仍在打包或依赖配置阶段。如果类已经存在,但运行时依然出现相同报错,需要确认设备上安装的是否就是刚刚分析的 APK,并在卸载旧包后重新安装。
5. 排查 R8/ProGuard
如果 Debug 包正常,而 Release 包会闪退,应重点检查代码压缩配置。可以先暂时关闭压缩进行对比。确认是裁剪问题后,再添加保留规则:
-keep class com.alipay.sdk.** { *; }
-dontwarn com.alipay.sdk.**
-dontwarn 只能抑制警告,无法把缺失的类重新加入安装包。防止类被裁剪的是 -keep,但前提仍然是支付宝 SDK 已经作为依赖参与构建。
不要长期使用大范围规则来掩盖依赖缺失。应先确认问题是否只出现在启用 R8/ProGuard 的构建中。
6. 清理构建缓存
修改插件或 Gradle 配置后,建议重新生成 Android 工程,并清理 Gradle 构建结果:
./gradlew clean
还需要卸载设备上的旧应用,再安装新包,避免因旧版本残留而误判:
adb uninstall com.funthinking.kaocheche
adb install app-release.apk
adb uninstall 会清除该应用在设备上的本地数据,执行前请确认测试数据可以删除。
调用代码示例
依赖配置正确后,可以在后台线程中创建 PayTask 并发起支付:
import android.app.Activity;
import com.alipay.sdk.app.PayTask;
import java.util.Map;
public void startAlipay(final Activity activity, final String orderInfo) {
new Thread(new Runnable() {
@Override
public void run() {
PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderInfo, true);
// 根据业务需要切换回主线程,
// 再把支付结果传递给 Unity 或更新界面。
}
}).start();
}
如果这段代码可以通过编译,但运行到 new PayTask(activity) 时崩溃,说明运行包中仍然缺少对应的类。修改线程逻辑无法解决这个问题。
Unity 接入时的注意事项
- 不要同时保留手动导入的 AAR 和通过 Maven 引入的同一套 SDK。
- 检查
Assets/Plugins/Android中是否残留旧版支付宝 SDK。 - 使用 External Dependency Manager 等依赖管理工具时,修改依赖后需要重新执行 Android Resolver。
- 如果支付宝 SDK 还依赖其他库,需要保证传递依赖完整,只复制单个 JAR 可能不够。
- APK 可以正常运行,不代表 AAB 一定正常。发布前还应验证由 AAB 生成并安装的实际构建产物。
- 支付订单字符串应由服务端生成并签名,不要把商户私钥放在 Unity 客户端中。
- 不能只根据客户端返回值判断支付结果。最终订单状态应由服务端结合支付宝异步通知或主动查询来确认。
建议按这个顺序定位:先检查 SDK 文件和 Gradle 依赖,再检查最终 APK 的 DEX。只有最终安装包中包含正确版本的 com.alipay.sdk.app.PayTask,这类 NoClassDefFoundError 才会消失。
备注:内容仅供参考。
