IAB 助手未设置。无法执行操作:queryInventory

IAB helper is not set up. Can't perform operation: queryInventory

我正在尝试在我的应用中实施应用内结算 API,但是当我 运行 我的应用出现异常时。这是我第一次处理应用内结算 API。这是我收到的异常日志:

Process: koemdzhiev.com.quickshoppinglist, PID: 10604
java.lang.RuntimeException: Unable to start activity ComponentInfo{koemdzhiev.com.quickshoppinglist/koemdzhiev.com.quickshoppinglist.ui.MainActivity}: java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access0(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
 Caused by: java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory
        at koemdzhiev.com.quickshoppinglist.utils.IabHelper.checkSetupDone(IabHelper.java:782)
        at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.java:610)
        at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.java:639)
        at koemdzhiev.com.quickshoppinglist.ui.MainActivity.queryPurchasedItems(MainActivity.java:187)
        at koemdzhiev.com.quickshoppinglist.ui.MainActivity.onStart(MainActivity.java:193)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)

我的主代码 activity:

public class MainActivity extends AppCompatActivity {
private static final String TAG =  MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private RecyclerView mRecyclerView;
private ArrayList<String> shoppingListItems;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
private TextView mEmptyTextView;
private ShoppingListAdapter adapter;
private ActionButton actionButton;
private MaterialDialog addItemdialog = null;
private AdView mAdView;
private IabHelper mHelper;
private String SKU_REMOVE_ADDS = "remove_adds_sku";
private boolean mIsRemoveAdds = false;
private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    @Override
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        if (result.isFailure()) {
            Log.d(TAG, "Error purchasing: " + result);
            return;
        }
        else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {
            // consume the gas and update the UI
            mIsRemoveAdds = true;
            mAdView.setVisibility(View.GONE);
            Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();
        }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
String publicKey = s1+s2+s3+s4+s5;

    mHelper = new IabHelper(this,publicKey);
    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        @Override
        public void onIabSetupFinished(IabResult result) {
            if (!result.isSuccess()) {
                //error
                Log.d(TAG, "Proglem setting up in-app Billing: " + result);
            }
            //Horay, IAB is fully set up!
            Log.d(TAG, "Horay, IAB is fully set up!");
            queryPurchasedItems();
        }
    });
private void queryPurchasedItems() {
    //check if user has bought "remove adds"
    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            if (result.isFailure()) {
                // handle error here
                Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();
            }
            else{
                // does the user have the premium upgrade?
                mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);
                if(!mIsRemoveAdds) {
                    Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();
                    mAdView = (AdView) findViewById(R.id.adView);
                    AdRequest adRequest = new AdRequest.Builder().build();
                    mAdView.loadAd(adRequest);
                }else{
                    mAdView.setVisibility(View.GONE);
                    Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();
                }

            }
        }
    };
    mHelper.queryInventoryAsync(mGotInventoryListener);
}
@Override
protected void onStart() {
    super.onStart();
    queryPurchasedItems();
    isListEmpty();
}

@Override
protected void onResume() {
    super.onResume();
    queryPurchasedItems();
    isListEmpty();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mHelper != null) mHelper.dispose();
    mHelper = null;
    mAdView.destroy();
}

您的 OnIabSetupFinishedListener 检查 (!result.isSuccess())

但你不 return 或在此处中止以防结果不成功。

我认为你的 mHelper.startSetup 失败了,你没有处理这个失败。

最后,我完成了整个工作,没有出现此异常 "IAB helper is not set up. Can't perform operation: queryInventory" 或我得到的 "Can't start async operation (consume) because another async operation(consume) is in progress"。

您要做的第一件事是在 IabHelper.java class 中添加 2 个方法:

 public boolean isAsyncInProgress(){
    return mAsyncInProgress;
}
public boolean isSetupDone (){
    return mSetupDone;
}

比你的主要 activity:

public class MainActivity extends AppCompatActivity {
private   IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        if (result.isFailure()) {
            // handle error here
            Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();
        }
        else{
            // does the user have the premium upgrade?
            mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);
            if(!mIsRemoveAdds) {
                Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();
                mAdView = (AdView) findViewById(R.id.adView);
                AdRequest adRequest = new AdRequest.Builder().build();
                mAdView.loadAd(adRequest);
            }else{
                mAdView.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();
            }

        }
    }
};
private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    @Override
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        if (result.isFailure()) {
            Log.d(TAG, "Error purchasing: " + result);
            return;
        }
        else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {
            // consume the gas and update the UI
            mIsRemoveAdds = true;
            mAdView.setVisibility(View.GONE);
            Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();
        }
    }
};

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
String publicKey = s1+s2+s3+s4+s5;

    mHelper = new IabHelper(this,publicKey);
    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        @Override
        public void onIabSetupFinished(IabResult result) {
            if (!result.isSuccess()) {
                //error
                Log.d(TAG, "Proglem setting up in-app Billing: " + result);
            }
            if (result.isSuccess()) {
                //Horay, IAB is fully set up!
                Log.d(TAG, "Horay, IAB is fully set up!");
                //queryPurchasedItems;
                mHelper.queryInventoryAsync(mGotInventoryListener);
            }
        }
    });

现在,正如 Google 的 guide 对 API 的建议,我们必须检查用户在开始或恢复方法中购买了哪些项目。这里我们将需要我们在 IabHelper.java class.

中添加的两个方法
   private void queryPurchasedItems() {
    //check if user has bought "remove adds"
    if(mHelper.isSetupDone() && !mHelper.isAsyncInProgress()) {
        mHelper.queryInventoryAsync(mGotInventoryListener);
    }
}

@Override
protected void onStart() {
    super.onStart();
    queryPurchasedItems();
}

@Override
protected void onResume() {
    super.onResume();
    queryPurchasedItems();
    isListEmpty();
}