webentwicklung-frage-antwort-db.com.de

Abrechnungs-API v3 IabHelper NullPointerException

edit 4/15: Das Abfangen von nullpointer in IabHelper scheint dieses Problem behoben zu haben. Ich sehe nicht mehr, dass die Ausnahmen geworfen werden, ich akzeptiere dies als Antwort.


edit 4/04: Ein wenig tiefer gehender Tauchgang. Es gibt Try-Catch-Blöcke, die RemoteExceptions und JSONExceptions für die queryPurchases-Methode behandeln, jedoch keine NullPointerException-Behandlung. Was ich versuchen werde, ist die NullPointer-Ausnahmebehandlung, so dass IabHelper beim Abfragen von querySkuDetails so aussieht:

    catch (NullPointerException e) {
        throw new IabException(IABHELPER_UNKNOWN_ERROR, "NullPointer while refreshing inventory.", e);
    }

Ich habe gerade einen Fehler zu diesem Thema eingereicht:

https://code.google.com/p/marketbilling/issues/detail?id=114


edit 3/25: Nun, immer noch diesen Absturz erhalten ... jetzt passiert es, als versucht wurde, einen Kontext in Zeile 3 des folgenden Auszuges von IabHelper zu erhalten:

int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
    logDebug("Querying owned items, item type: " + itemType);
    logDebug("Package name: " + mContext.getPackageName());

Das ist frustrierend, da ich in meinem Manifest immer den vollständigen Pfadnamen meiner App für "name" verwende.

Beispiel "com.myappname.blah.ClassName"

Ich habe auch versucht, dies, MyClass.this, getApplicationContext () an mHelper zu übergeben. Sie produzieren jedoch alle zufällig die gleichen NullPointer-Ergebnisse von Geräten in der Wildnis. Ich habe im Manifest auch name = ". MyClass" ausprobiert. So sieht es aktuell aus:

mHelper = new IabHelper(MyClass.this, myKey);

edit 18.03.13: Ich bekomme immer noch Ausnahmen, auch wenn die neue IabHelper-Version am 17.03. installiert ist. 

Ich fange an, hier ein Muster zu sehen, dass alle Abstürze auftreten, wenn versucht wird, einen Kontext abzurufen, wenn mContext.getPackageName () ausgeführt wird. Ich bin neugierig, warum dies auf allen meinen Testgeräten funktioniert, und ich kann diesen Absturz nicht reproduzieren und scheint nur auf einer kleinen Anzahl von Geräten zu sein.

Hier ist der neue Absturz:

Java.lang.NullPointerException
    at com.myapp.util.IabHelper.queryPurchases(SourceFile:836)
    at com.myapp.util.IabHelper.queryInventory(SourceFile:558)
    at com.myapp.util.IabHelper.queryInventory(SourceFile:522)
    at com.myapp.util.IabHelper$2.run(SourceFile:617)
    at Java.lang.Thread.run(Thread.Java:1019)

Verursacht durch IabHelper ...

line 836: logDebug("Package name: " + mContext.getPackageName());

edit 17.03.13: Ich habe festgestellt, dass in den letzten Monaten viele Bugfixes veröffentlicht wurden. Ich werde den neuesten hier verfügbaren Code ausprobieren und sehen, ob das Problem dadurch gelöst wird:

https://code.google.com/p/marketbilling/source/browse/v3/src/com/example/Android/trivialdrivesample/util


In einer meiner Apps verwende ich die Abrechnungs-API und den darin enthaltenen Zusatzcode.

Ich verwende die neueste Version der Abrechnungs-API, die über den SDK-Manager ab dem 16.03.2013 verfügbar ist.

In meiner Aktivität frage ich das Inventar folgendermaßen ab:

final List<String> skuList = new ArrayList<String>();
skuList.add("sku1");
skuList.add("sku2");
skuList.add("sku3");
if (skuList != null) {
    if (skuList.size() > 0) {
        try {
            mHelper.queryInventoryAsync(true, skuList, mGotInventoryListener);
        } catch (Exception e) { 
            ACRA.getErrorReporter().handleException(e);
        }
    }
}

Ich erhalte in der Wildnis mehrere NullPointerException-Berichte von der IabHelper-Klasse für die folgenden Geräte. Ich kann das Problem nicht reproduzieren und kann keine Informationen zu diesen Abstürzen finden. Dies ist der Grund, warum ich diese Frage poste.

Ich habe unzählige andere Überprüfungen auf Nullwerte und Try/Catch-Blöcke im Teil "Abwicklungs-API" für Entwickler, einschließlich onQueryInventoryFinished. Ich weiß, dass diese Ausnahme nicht aus "meinem Code" geworfen wird (da ich keine Abstürze erfasse.) von allen Klassen meiner App), sondern wird aus dem IabHelper selbst geworfen. Ich habe den IabHelper mit Ausnahme dieses empfohlenen Updates nicht geändert: https://stackoverflow.com/a/14737699

Crash # 1 Galaxy Nexus

Java.lang.NullPointerException
    at com.myapp.util.IabHelper.querySkuDetails(SourceFile:802)
    at com.myapp.util.IabHelper.queryInventory(SourceFile:471)
    at com.myapp.util.IabHelper$2.run(SourceFile:521)
    at Java.lang.Thread.run(Thread.Java:856)

Verursacht durch IabHelper ...

line 802: Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), ITEM_TYPE_INAPP, querySkus);    

Crash # 2 Samsung GT-S5570L

Java.lang.NullPointerException
    at com.myapp.util.IabHelper.queryPurchases(SourceFile:735)
    at com.myapp.util.IabHelper.queryInventory(SourceFile:465)
    at com.myapp.util.IabHelper$2.run(SourceFile:521)
    at Java.lang.Thread.run(Thread.Java:1019)

Verursacht durch IabHelper ...

line 735: Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(), ITEM_TYPE_INAPP, continueToken);
51
logray

edit 4/15: Das Abfangen von nullpointer in IabHelper scheint dieses Problem behoben zu haben. Ich sehe nicht mehr, dass die Ausnahmen geworfen werden, ich akzeptiere dies als Antwort.


edit 4/04: Ein wenig tiefer gehender Tauchgang. Es gibt Try-Catch-Blöcke, die RemoteExceptions und JSONExceptions für die Methode queryPurchases verarbeiten, jedoch keine NullPointerException-Behandlung. Was ich versuchen werde, ist die NullPointer-Ausnahmebehandlung, so dass IabHelper beim Abfragen von querySkuDetails so aussieht:

    catch (NullPointerException e) {
        throw new IabException(IABHELPER_UNKNOWN_ERROR, "NullPointer while refreshing inventory.", e);
    }

Ich habe gerade einen Fehler zu diesem Thema eingereicht:

https://code.google.com/p/marketbilling/issues/detail?id=114


Veränderung

        if (querySkuDetails) {
            r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus);
            if (r != BILLING_RESPONSE_RESULT_OK) {
                throw new IabException(r, "Error refreshing inventory (querying prices of items).");
            }
        }

zu

        if (querySkuDetails) {
            try {
                r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus);
                if (r != BILLING_RESPONSE_RESULT_OK) {
                    throw new IabException(r, "Error refreshing inventory (querying prices of items).");
                }
            } catch (NullPointerException e) {
                throw new IabException(IABHELPER_UNKNOWN_ERROR, "NPE while refreshing inventory.", e);
            }
        }

Veränderung

            if (querySkuDetails) {
                r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreSubsSkus);
                if (r != BILLING_RESPONSE_RESULT_OK) {
                    throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions).");
                }
            }

zu

            if (querySkuDetails) {
                try {
                    r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreSubsSkus);
                    if (r != BILLING_RESPONSE_RESULT_OK) {
                        throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions).");
                    }
                } catch (NullPointerException e) {
                    throw new IabException(IABHELPER_UNKNOWN_ERROR, "NPE while refreshing inventory.", e);
                }
            }
23
logray

Sie verwenden wahrscheinlich asynchrone Operationen. Der aktuelle IabHelper ist nicht sicher, wenn Sie die ... async-Methoden verwenden. Das Problem ist, dass in jedem Moment eine asynchrone Operation ausgeführt wird und dispose im Haupt-Thread aufgerufen werden kann. In diesem Fall erhalten Sie NullPointerExceptions und IllegalStateExceptions. 

Hier ist der Patch, der es repariert:

Index: src/com/evotegra/aCoDriver/iabUtil/IabHelper.Java
===================================================================
--- src/com/evotegra/aCoDriver/iabUtil/IabHelper.Java   (revision 1162)
+++ src/com/evotegra/aCoDriver/iabUtil/IabHelper.Java   (working copy)
@@ -86,7 +86,10 @@

     // Is an asynchronous operation in progress?
     // (only one at a time can be in progress)
-    boolean mAsyncInProgress = false;
+    volatile boolean mAsyncInProgress = false;
+    
+    // is set to true if dispose is called while a thread is running. Allows graceful shutdown
+    volatile boolean mDisposeRequested = false;

     // (for logging/debugging)
     // if mAsyncInProgress == true, what asynchronous operation is in progress?
@@ -285,6 +288,12 @@
      * disposed of, it can't be used again.
      */
     public void dispose() {
+       // do not dispose while an async Thread is running. Will cause all kinds of exceptions.
+       // In this case dispose must be called from thread after setting mAsyncInProgress to true
+       if (mAsyncInProgress) {
+           mDisposeRequested = true;
+           return;
+       }
         logDebug("Disposing.");
         mSetupDone = false;
         if (mServiceConn != null) {
@@ -827,6 +836,7 @@
         logDebug("Ending async operation: " + mAsyncOperation);
         mAsyncOperation = "";
         mAsyncInProgress = false;
+        if (mDisposeRequested) IabHelper.this.dispose();
     }

Oder laden Sie den Patch hier herunter . http://code.google.com/p/marketbilling/issues/detail?id=139&thanks=139&ts=1375614409

20
tmanthey

Ändern Sie den Anfang der queryPurchases-Methode geringfügig, sodass sie folgendermaßen aussieht:

int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
        // Query purchases
        //logDebug("Querying owned items, item type: " + itemType);
       //logDebug("Package name: " + mContext.getPackageName());
       boolean verificationFailed = false;
       String continueToken = null;

        do {
//            logDebug("Calling getPurchases with continuation token: " + continueToken);
            if(mDisposed || mService==null) return IABHELPER_UNKNOWN_ERROR;
            Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),
                    itemType, continueToken);

Danke an sebastie für den Hinweis auf die Ursache.

0
Thunder

tmantheypatch erfordert ebenfalls

mDisposeRequested = false;

nach der entsorgung erfolgt

0