Android in-app billing: Can't start async oper

2019-01-16 03:20发布

I am using the IabHelper utility classes, as recommended by Google's tutorial, and I'm being hit hard by this error. Apparently IabHelper can not run multiple async operations at the same time. I even managed to hit it by trying to start a purchase while the inventory taking was still in progress.

I have already tried to implement onActivityResult in my main class as suggested here, but I don't even get a call to that method before the error hits. Then I found this but I have no idea where to find this flagEndAsync method - it's not in the IabHelper class.

Now I'm looking for a way around this (without reimplementing the whole she-bang). The only solution I can think of is to create a boolean field asyncActive that is checked before an async task is started, and not do it if there is another task active. But that has many other problems, and doesn't work across activities. Also I'd prefer to have an async task queue up and run as soon as it's allowed to, instead of not running at all.

Any solutions for this issue?

19条回答
爷、活的狠高调
2楼-- · 2019-01-16 03:43

This was not easy to crack but I found the needed workarounds. Quite disappointed with Google lately, their Android web sites have become a mess (very hard to find useful info) and their sample code is poor. When I was doing some Android development a few years ago it all went so much easier! This is yet another example of that...

Indeed IabUtil is buggy, it does not properly call off its own async tasks. The complete set of necessary workarounds to stabilise this thing:

1) make method flagEndAsync public. It is there, just not visible.

2) have every listener call iabHelper.flagEndAsync to make sure the procedure is marked finished properly; it seems to be needed in all listeners.

3) surround calls with a try/catch to catch the IllegalStateException which may occur, and handle it that way.

查看更多
SAY GOODBYE
3楼-- · 2019-01-16 03:43

Find flagEndAsync() inside IabHelper.java file and make it public function .

Before trying purchase call flagEndAsync() for your IabHelper .

you must do somthig like this code :

mHelper.flagEndAsync();
mHelper.launchPurchaseFlow(AboutActivity.this, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, "payload-string");
查看更多
Animai°情兽
4楼-- · 2019-01-16 03:49

Really annoying issue. Here is a quick and dirty solution that is not perfect code wise, but that is user friendly and avoids bad ratings and crashes:

if (mHelper != null) {
        try {
        mHelper.launchPurchaseFlow(this, item, RC_REQUEST, mPurchaseFinishedListener, "");
        }       
        catch(IllegalStateException ex){
            Toast.makeText(this, "Please retry in a few seconds.", Toast.LENGTH_SHORT).show();
        }
    }

This way the user just has to tap another time (2 times at worst) and gets the billing popup

Hope it helps

查看更多
叼着烟拽天下
5楼-- · 2019-01-16 03:50

Make sure that you call the IabHelper's handleActivityResult in the Activity's onActivityResult, and NOT in the Fragment's onActivityResult.

The following code snippet is from TrivialDrive's MainActivity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
    if (mHelper == null) return;

    // Pass on the activity result to the helper for handling
    if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
        // not handled, so handle it ourselves (here's where you'd
        // perform any handling of activity results not related to in-app
        // billing...
        super.onActivityResult(requestCode, resultCode, data);
    }
    else {
        Log.d(TAG, "onActivityResult handled by IABUtil.");
    }
}

Update:

  • There is now a In-app Billing Version 3 API (what was the version in 2013?)
  • The code sample has moved to Github. Snippet above edited to reflect current sample, but is logically the same as before.
查看更多
迷人小祖宗
6楼-- · 2019-01-16 03:51

Or, you can get the latest IabHelper.java file here: https://code.google.com/p/marketbilling/source/browse/

The March 15th version fixed this for me. (Note other files with no changes were committed on the 15th)

I still had to fix one crash that happened during testing caused by a null intent extras when "android.test.canceled" was the sent SKU. I changed:

int getResponseCodeFromIntent(Intent i) {
    Object o = i.getExtras().get(RESPONSE_CODE);

to:

int getResponseCodeFromIntent(Intent i) {
    Object o = i.getExtras() != null ? i.getExtras().get(RESPONSE_CODE) : null;
查看更多
Explosion°爆炸
7楼-- · 2019-01-16 03:52

Yes, i am also facing this issue but i resolved this but i resolved using

IabHelper mHelpermHelper = new IabHelper(inappActivity, base64EncodedPublicKey);
  mHelper.flagEndAsync();

The above method stop all the flags. Its work for me must check

查看更多
登录 后发表回答