Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android in-app billing: Can't start async operation because another async operation (is in progress)

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?

like image 573
Wouter Avatar asked Mar 22 '13 16:03

Wouter


2 Answers

A simple tricky solution

before calling purchaseItem method just add this line

  if (billingHelper != null) billingHelper.flagEndAsync(); 

so your code looks this way

 if (billingHelper != null) billingHelper.flagEndAsync();  purchaseItem("android.test.purchased"); 

Note: don't forget to make public flagEndAsync() method in IabHelper if you call it from another package.

like image 99
Khan Avatar answered Sep 25 '22 17:09

Khan


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.
like image 44
Jonathan Lin Avatar answered Sep 21 '22 17:09

Jonathan Lin