You're probably getting the exception because somewhere in the activity lifecycle, you called mHelper.dispose()
, then tried to use that same disposed instance later on. My recommendation is to only dispose of mHelper in onDestroy()
and recreate it in onCreate()
.
However, you will run into another problem with IabHelper and device rotation. The problem goes like this: in your activity's onCreate()
, you create the IabHelper instance mHelper and set it up. Later, you call mHelper.launchPurchaseFlow(...)
and the IAB popup dialog appears floating above your activity. Then you rotate the device, and the IabHelper instance gets disposed of in onDestroy(...)
then recreated in onCreate(...)
. The IAB dialog is still showing, you press the purchase button, and the purchase completes. onActivityResult()
is then called on your activity, and you naturally call mHelper.handleActivityResult(...)
. The problem is, launchPurchaseFlow(...)
has never been called on the recreated instance of IabHelper. IabHelper only handles the activity result in handleActivityResult(...)
if launchPurchaseFlow(...)
has been previously called on the current instance. Your OnIabPurchaseFinishedListener will never be called.
My solution to this was to modify IabHelper to allow you to tell it to expect handleActivityResult(...)
without calling launchPurchaseFlow(...)
. I added the following to
IabHelper.java
public void expectPurchaseFinished(int requestCode, OnIabPurchaseFinishedListener listener)
{
mRequestCode = requestCode;
mPurchaseListener = listener;
}
This will cause IabHelper to call onIabPurchaseFinished(...)
on the listener when handleActivityResult(...)
is called. Then, you do this:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
mHelper.expectPurchaseFinished(requestCode, mPurchaseFinishedListener);
mHelper.handleActivityResult(requestCode, resultCode, data);
}
My entire copy of IabHelper can be found here https://gist.github.com/benhirashima/7917645. Note that I updated my copy of IabHelper with the version found in this commit, which fixes a few bugs and has not been published in the Android SDK Manager. Also note that there are newer commits, but they contain new bugs and should not be used.
expectPurchaseFinished
implied, but I eventually realized that you're setting a new instance of purchaseFinishedListener just before handling the result, which guarantees that there is a listener to handle the purchasedFinished event even if the activity and iabHelper were recreated. – Principled