Probabilmente stai ricevendo l'eccezione perché da qualche parte nel ciclo di vita di attività, hai chiamato mHelper.dispose()
, poi ha cercato di utilizzare lo stesso istanza dismessa in seguito. La mia raccomandazione è di disporre solo di mHelper in onDestroy()
e ricrearlo in onCreate()
.
Tuttavia, si verificherà un altro problema con IabHelper e rotazione del dispositivo. Il problema è simile a questo: nella tua attività onCreate()
, crei l'istanza di IHHelper mHelper e la configuri. Successivamente, chiami mHelper.launchPurchaseFlow(...)
e la finestra di dialogo IAB appare fluttuante sopra la tua attività. Quindi si ruota il dispositivo e l'istanza di IabHelper viene eliminata in onDestroy(...)
quindi ricreata in onCreate(...)
. La finestra di dialogo IAB continua a essere visualizzata, si preme il pulsante di acquisto e l'acquisto viene completato. onActivityResult()
viene quindi chiamato sulla tua attività, e naturalmente chiama mHelper.handleActivityResult(...)
. Il problema è che launchPurchaseFlow(...)
non è mai stato chiamato nell'istanza ricreata di IabHelper. IabHelper gestisce solo il risultato dell'attività in handleActivityResult(...)
se in precedenza è stato chiamato launchPurchaseFlow(...)
nell'istanza corrente. Il tuo OnIabPurchaseFinishedListener non verrà mai chiamato.
La mia soluzione a questo era di modificare IabHelper per consentire di dire che aspettarsi handleActivityResult(...)
senza chiamare launchPurchaseFlow(...)
. Ho aggiunto il testo seguente IabHelper.java
public void expectPurchaseFinished(int requestCode, OnIabPurchaseFinishedListener listener)
{
mRequestCode = requestCode;
mPurchaseListener = listener;
}
Questo farà sì che IabHelper chiamare onIabPurchaseFinished(...)
sull'ascoltatore quando handleActivityResult(...)
si chiama. Quindi, si esegue questa operazione:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
mHelper.expectPurchaseFinished(requestCode, mPurchaseFinishedListener);
mHelper.handleActivityResult(requestCode, resultCode, data);
}
Tutta la mia copia di IabHelper può essere trovato qui https://gist.github.com/benhirashima/7917645. Nota che ho aggiornato la mia copia di IabHelper con la versione trovata in this commit, che corregge alcuni bug e non è stata pubblicata in Android SDK Manager. Si noti inoltre che ci sono newer commits, ma contengono new bugs e non devono essere utilizzati.
fonte
2013-12-11 22:19:20
Soluzione pulita per quanto riguarda la gestione dell'evento di rotazione. Ho avuto qualche problema a capire cosa implica "expectPurchaseFinished", ma alla fine mi sono reso conto che stai impostando una nuova istanza di purchaseFinishedListener appena prima di gestire il risultato, che garantisce che ci sia un listener per gestire l'evento SelectedFinished anche se l'attività e iabHelper erano ricreato. –
Possiamo estendere la stessa idea per gestire mPurchasingItemType (importa solo se si utilizzano sia subs e inapp, ad esempio use onSaveInstanceState e onRestoreInstanceState, quindi impostare il tipo di elemento corretto se non è impostato). –