You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Unity IAP实现安卓应用订阅升降级遇到空引用错误如何解决

报错根本原因

你代码里触发空引用异常的核心问题出在遍历商品的逻辑顺序:

  • 你在未判断p.hasReceipt是否为真的前提下,直接调用new GooglePurchaseData(p.receipt)构造收据对象。当遍历到没有购买记录的商品时,p.receipt为null,直接传入构造函数就会触发空引用异常,和你logcat输出的报错完全吻合。
  • 另外还存在两个潜在风险:
    • 遍历到第一个有收据的商品就直接中断,没有校验该订阅是否仍在生效周期内,可能传入过期订阅的商品对象触发后续升级接口报错
    • 拿到data.json.productId重新查找oldProduct后,没有校验oldProduct.receipt是否存在就直接构造第二个GooglePurchaseData,极端场景下也会触发空引用

修复方案

调整遍历逻辑的执行顺序,增加必要的空校验,修改后的代码如下:

public void Buy1YearSubscription()
{
    print("trying to buy 12 months of subscription");
    bool alreadyHaveSomeSubscription = false;
    Product oldProduct = null;
    // 先遍历所有商品,找有效订阅
    foreach (Product p in m_StoreController.products.all)
    {
        // 先判断有没有收据,再处理后续逻辑
        if (p.hasReceipt && !string.IsNullOrEmpty(p.receipt))
        {
            GooglePurchaseData data = new GooglePurchaseData(p.receipt);
            // 可选:加订阅有效性校验,比如判断过期时间大于当前时间,避免拿过期订阅升级
            // if(data.json.purchaseTime + 订阅时长 > 现在时间) 再往下走
            alreadyHaveSomeSubscription = true;
            oldProduct = p; // 直接用当前遍历到的有效商品,不用再重新查一次,减少空引用风险
            print("Has the receipt of-----" + data.json.productId);
            break;
        }
    }
    if (!alreadyHaveSomeSubscription || oldProduct == null)
    {
        print("no previous valid subscription");
        BuyProductID(_1YearSubscription);
    }
    else
    {
        print("upgrading to 1year");
        Product newProduct = m_StoreController.products.WithID(_1YearSubscription);
        // 额外校验新商品是否存在,避免空引用
        if(newProduct == null)
        {
            Debug.LogError("New subscription product not found");
            return;
        }
        SubscriptionManager.UpdateSubscriptionInGooglePlayStore(oldProduct, newProduct, (string msg1, string msg2) =>
        {
            IgoogleplayStoreExtention.UpdateSubscription(oldProduct, newProduct, GooglePlayStoreProrationMode.ImmediateWithoutProration);
        });
    }
}

额外排查点

如果修改后仍有报错,可以检查以下两点:

  • 确保Google Play控制台里三个订阅档位都属于同一个订阅组,否则无法跨组升级
  • 内部测试阶段请用配置的测试账号购买订阅,不要用正式账号,避免缓存的收据数据异常

内容的提问来源于stack exchange,提问作者Ashish Rana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 10:00:05