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

Android应用内购上线后触发IllegalStateException崩溃问题求助

解决Google Play上线后IabHelper的IllegalStateException崩溃问题

你遇到的这个java.lang.IllegalStateException是IabHelper生命周期管理不当导致的典型问题,测试环境正常但生产环境出问题,主要是因为线上用户的操作场景更复杂(比如后台进程被系统回收、快速切换页面等),而你的代码里缺少对IabHelper状态的必要校验和资源释放逻辑。

问题根源分析

从崩溃栈来看,异常来自IabHelper的checkNotDisposed、checkSetupDone等方法,说明你在以下场景调用了IabHelper的方法:

  • IabHelper已经被dispose()销毁后
  • IabHelper的初始化(startSetup)还未完成时
  • 异步回调执行时,对应的Activity已经被销毁,IabHelper实例处于无效状态

具体修复方案

1. 正确管理IabHelper的生命周期,在Activity销毁时释放资源

你的代码里只在onCreate初始化了IabHelper,但没有在Activity销毁时清理资源,这会导致异步回调执行时IabHelper已经处于非法状态。在你的Activity中添加以下代码:

@Override
protected void onDestroy() {
    super.onDestroy();
    // 释放IabHelper资源,避免内存泄漏和非法状态调用
    if (mHelper != null) {
        mHelper.dispose();
        mHelper = null;
    }
}

2. 在调用IabHelper方法前,先校验状态

在调用queryInventoryAsync、launchPurchaseFlow等方法前,必须确保IabHelper已经初始化完成且未被销毁。修改你的checkItem方法:

public void checkItem() {
    // 先检查mHelper是否存在、已完成初始化且未被销毁
    if (mHelper != null && mHelper.isSetupDone() && !mHelper.isDisposed()) {
        mHelper.queryInventoryAsync(mReceivedInventoryListener);
    }
}

3. 增强异步回调中的安全校验

在异步回调(比如onQueryInventoryFinished、onIabPurchaseFinished)中,除了检查mHelper == null,还要校验是否已被销毁,避免后续操作触发异常:

IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        // 双重校验:实例存在且未被销毁
        if (mHelper == null || mHelper.isDisposed()) {
            return;
        }
        Purchase purchase = inventory.getPurchase(ITEM_SKU);
        if (purchase != null) {
            removeAds();
        }
    }
};

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        if (mHelper == null || mHelper.isDisposed()) {
            return;
        }
        if (result.isFailure()) {
            checkItem();
            return;
        } else if (purchase.getSku().equals(ITEM_SKU)) {
            removeAds();
        }
    }
};

4. 跟踪初始化状态,避免提前调用方法

可以添加一个布尔变量标记IabHelper是否初始化完成,防止在startSetup回调前就调用内购相关方法:

private boolean mIsIabSetupComplete = false;

// 在onCreate的startSetup回调中更新状态
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
    public void onIabSetupFinished(IabResult result) {
        if (!result.isSuccess()) {
            Log.d(TAG, "In-app Billing setup failed: " + result);
            mIsIabSetupComplete = false;
        } else {
            Log.d(TAG, "In-app Billing is set up OK");
            mIsIabSetupComplete = true;
            // 初始化完成后再执行首次库存查询等操作
            checkItem();
        }
    }
});

// 然后在checkItem中增加这个状态校验
public void checkItem() {
    if (mHelper != null && mIsIabSetupComplete && !mHelper.isDisposed()) {
        mHelper.queryInventoryAsync(mReceivedInventoryListener);
    }
}

为什么测试环境没问题?

测试时你通常不会频繁触发Activity销毁重建、系统回收进程等场景,IabHelper的状态一直处于有效状态,所以不会触发异常。但线上用户的操作场景多样,这些边缘情况很容易出现,因此必须做好状态校验和资源管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:49:08