PAYATHON 2026

未安装支付宝支付 APK 时网页支付出现空指针异常

支付小周

结论

异常出现在支付宝 SDK 的 H5PayActivity.onDestroy() 内部,是网页支付页面销毁时访问空对象导致的。由于崩溃发生在 SDK 自身的 Activity 生命周期中,业务代码里的判空或支付调用异常捕获通常解决不了这个问题。

建议先升级到支付宝开放平台当前提供的 Android 支付 SDK,彻底删除旧版 SDK 后重新集成。如果使用最新版仍能复现,请将完整日志和复现步骤提交给支付宝技术支持。不要反编译或修改 com.alipay.sdk.* 的内部代码。

原因分析

异常的关键位置是:

com.alipay.sdk.app.H5PayActivity.onDestroy(SourceFile:119)

SDK 执行 onDestroy() 时调用了:

com.alipay.sdk.widget.g.a()

此时对应的 g 对象可能尚未初始化,也可能已经提前释放,从而触发 NullPointerException。

常见的触发流程如下:

  1. 设备没有安装支付宝客户端。
  2. SDK 降级为 H5 网页支付。
  3. 用户关闭支付页面,或者系统销毁 H5PayActivity。
  4. 旧版 SDK 清理网页支付组件时,没有正确处理空对象。

堆栈全部指向支付宝 SDK 内部的 Activity,而不是应用自身的 Activity。因此,在业务代码中增加 try-catch,无法拦截页面销毁阶段发生的异常。

解决步骤

1. 升级支付宝支付 SDK

从支付宝开放平台下载当前推荐的 Android 支付 SDK,替换项目中的旧版 AAR 或 JAR。题目没有提供当前使用的 SDK 版本,因此不宜指定固定版本号,应以支付宝开放平台目前发布的版本为准。

如果项目使用本地 AAR,可按实际文件名配置:

dependencies {
    implementation files('libs/alipaysdk.aar')
}

替换时还要检查并删除:

  • 旧版 alipaySdk-*.jar
  • 旧版 alipaysdk-*.aar
  • 其他模块中重复引用的支付宝 SDK
  • 手工复制且已由新版 SDK 自动合并的组件声明

不要让新旧版本同时进入最终 APK,否则可能引发类冲突,运行时也可能仍然加载旧实现。

可通过 Gradle 依赖报告检查重复依赖:

./gradlew app:dependencies

替换完成后执行 Clean/Rebuild,并卸载设备上的旧应用再重新安装,避免构建缓存或旧安装包干扰验证结果。

2. 保持标准的支付调用方式

支付请求应在线程中执行,取得结果后再切换到主线程处理:

ExecutorService executor = Executors.newSingleThreadExecutor();

executor.execute(() -> {
    PayTask payTask = new PayTask(activity);
    Map<String, String> result = payTask.payV2(orderInfo, true);

    activity.runOnUiThread(() -> {
        String resultStatus = result.get("resultStatus");

        if ("9000".equals(resultStatus)) {
            // 客户端结果仅用于界面提示,最终支付状态应由服务端异步通知确认
        } else if ("6001".equals(resultStatus)) {
            // 用户取消支付
        } else {
            // 支付失败、结果未知或其他状态
        }
    });
});

这里的 try-catch 只能处理支付调用期间抛出的异常:

executor.execute(() -> {
    try {
        PayTask payTask = new PayTask(activity);
        Map<String, String> result = payTask.payV2(orderInfo, true);
        // 处理同步返回结果
    } catch (Exception e) {
        Log.e("Alipay", "Failed to invoke Alipay SDK", e);
    }
});

它无法保证捕获 H5PayActivity.onDestroy() 中的崩溃,因为异常发生在另一个 Activity 的生命周期回调里。

3. 在目标设备上验证 H5 支付路径

升级后应重点验证以下场景:

  • 未安装支付宝客户端时发起支付
  • 点击网页支付页面的关闭或返回按钮
  • 连续多次进入和退出支付页面
  • 支付过程中将应用切到后台后再恢复
  • 横竖屏切换以及系统回收 Activity

题目提到的华为 LIO-AL00 和 Android 10 应纳入必要的回归测试环境,但仅凭当前日志,不能认定问题只出现在该机型或 EMUI 上。

如果升级后仍然出现

请保留以下信息并提交给支付宝技术支持:

  • 支付 SDK 的准确版本
  • 完整的崩溃堆栈,不要只截取 Caused by
  • 手机型号、Android 版本和 EMUI 版本
  • 设备是否安装支付宝客户端
  • 关闭页面时的具体操作路径
  • 最小可复现工程或录屏
  • 混淆前后是否都能复现
  • APK 使用的 ABI、构建类型和依赖报告

不要尝试继承、替换或通过反射操作 H5PayActivity、H5AuthActivity、com.alipay.sdk.widget.g 等内部类。这些类不是稳定的公开 API,可能导致签名校验、支付流程或后续升级出现异常。

注意事项

支付是否成功,必须以服务端收到并通过验签的支付宝异步通知为准,不能只看 payV2() 的客户端返回值。

如果短期内无法升级 SDK,可以考虑由服务端提供独立的浏览器支付方案作为临时降级路径,具体是否适用取决于签约产品和支付宝开放平台的接入规则。直接屏蔽 onDestroy() 异常、修改 SDK 字节码或设置全局未捕获异常处理器,都无法从根本上解决这个问题。

备注:内容仅供参考。