React-native-iap: Android stürzt nach der Veröffentlichung auf vielen Geräten ab

Erstellt am 9. Nov. 2018  ·  45Kommentare  ·  Quelle: dooboolab/react-native-iap

Version von react-native-iap

"reaktionsnativ": "0,55,4"
"react-native-iap": "^ 2.3.2"

Plattformen, auf denen Sie den Fehler hatten (IOS oder Android oder beides?)

Android

Erwartetes Verhalten

Bitte helfen Sie mir, ich muss das sofort beheben. Weil es bereits + 2k Benutzer gibt

Tatsächliches Verhalten

App stürzt aufgrund von rniap auf vielen Geräten ab. In der Spielekonsole habe ich gesehen, dass dieser Fehler den Absturz verursacht:
java.lang.RuntimeException:

  1. unter com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
  2. unter com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
  3. at com.dooboolab.RNIap.RNIapModule $ 4.run (RNIapModule.java:154)
  4. at com.dooboolab.RNIap.RNIapModule $ 3.onBillingSetupFinished (RNIapModule.java:123)
  5. at com.android.billingclient.api.BillingClientImpl $ BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
  6. at android.app.LoadedApk $ ServiceDispatcher.doConnected (LoadedApk.java:1264)
  7. at android.app.LoadedApk $ ServiceDispatcher $ RunConnection.run (LoadedApk.java:1281)
  8. bei android.os.Handler.handleCallback (Handler.java:815)
  9. bei android.os.Handler.dispatchMessage (Handler.java:104)
  10. bei android.os.Looper.loop (Looper.java:207)
  11. bei android.app.ActivityThread.main (ActivityThread.java:5692)
  12. at java.lang.reflect.Method.invoke (native Methode)
  13. at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:908)
  14. bei com.android.internal.os.ZygoteInit.main (ZygoteInit.java:769)

Getestete Umgebung (Emulator? Reales Gerät?)

Hier ist der Bericht von der Spielkonsole:
https://ibb.co/gDxZQA

Schritte zum Reproduzieren des Verhaltens

Ich weiß nicht, was ich tun soll, ich habe rniap wie im Beispiel verwendet.
in componentDidMount:
Versuchen {
const result = warte auf RNIap.initConnection ();
} catch (err) {
console.log (err);
}}
in componentWillUnmount:
RNIap.endConnection ();

🐛 bug 🤖 android

Hilfreichster Kommentar

@hyochan Entschuldigung, ich hatte gestern keine Zeit, mir das anzuschauen, hoffentlich kann ich bald einen Blick darauf werfen

@ Ilario17 Es ist wahrscheinlich zu vorliegt. Um fair zu sein, sollten wir diese Methode nicht mehrmals aufrufen

edit: ah, das Problem tritt auf, wenn onBillingSetupFinished mehr als einmal vorkommt. In ensureConnection wir den Listener entfernen, wenn wir fertig sind (dh wenn wir callback.run() anrufen oder das abgegebene Versprechen ablehnen). Sollte eine einfache PR sein, wenn jemand Lust auf freies Karma hat! Ansonsten werde ich versuchen, es bald zu erreichen

Alle 45 Kommentare

Könnten Sie unsere aktuelle Version 2.3.19 und Comeback ausprobieren?

Ich kann nicht Weil es eine unmittelbare Situation war. Also habe ich das iap-Paket geändert. Jetzt gibt es keine Abstürze bei + 3k Benutzern. Aber danke. Ich werde es in meinem nächsten Projekt versuchen.

Hallo, können Sie dieses Problem erneut öffnen? Ich habe das gleiche Problem und verwende Version 2.3.21

java.lang.RuntimeException:
unter com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
unter com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
at com.dooboolab.RNIap.RNIapModule $ 4.run (RNIapModule.java:155)
at com.dooboolab.RNIap.RNIapModule $ 3.onBillingSetupFinished (RNIapModule.java:124)
at com.android.billingclient.api.BillingClientImpl $ BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
at android.app.LoadedApk $ ServiceDispatcher.doConnected (LoadedApk.java:1658)
at android.app.LoadedApk $ ServiceDispatcher $ RunConnection.run (LoadedApk.java:1687)
bei android.os.Handler.handleCallback (Handler.java:789)
bei android.os.Handler.dispatchMessage (Handler.java:98)
bei android.os.Looper.loop (Looper.java:164)
bei android.app.ActivityThread.main (ActivityThread.java:6938)
at java.lang.reflect.Method.invoke (native Methode)
at com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:327)
bei com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

Das ist mein componentDidMount

           const itemSKus = Platform.select({
            ios: [
                ...
            ],
            android: [
                ...
            ]
        });

        try {
            const message = await RNIap.initConnection();
            //console.log(`message = ${message}`);
            const items = await RNIap.getProducts(itemSKus);
            //console.log(`items = ${items.length}`);
            //console.log(items);
            this.props.storeInAppPurchaseList(items);
        } catch (errorCode) {
            console.log(`error rniap = ${errorCode}`);
        }

@LinusU Könnten Sie uns hier helfen? Warum stürzt callback.run() bei der Veröffentlichung ab? Sollten wir prüfen, ob callback in ensureConnection null ist? Hm. es ist ein runtime exception .

Hmmm, was bedeutet RuntimeException hier, gibt es keine weiteren Informationen? @hyochan warum denkst du, dass callback null ? 🤔

@LinusU Danke für dein Feedback. Ich habe derzeit keine Ahnung. Ich habe gerade die Problemzeile unten gesehen.
image

In RNIapModule.java Zeile 124,

callback.run();

Hast du noch eine Idee?

@LinusU Wenn Sie keine Ahnung davon haben, würde ich in Betracht ziehen, dies auf den vorherigen Stand zurückzusetzen.

Okay, hier ist das Problem:

https://github.com/facebook/react-native/blob/370bcffba748e895ad8afa825bfef40bff859c95/ReactAndroid/src/main/java/com/facebook/react/bridge/CallbackImpl.java#L27 -L31

Aus irgendeinem Grund rufen wir den Rückruf mehrmals auf, sollte einfach zu beheben sein!

@LinusU Sieht gut aus, weil du in einer Spur bist! Könnten Sie uns dafür ein PR ?

Warum gibt es in dieser Methode eine RuntimeException?

if (!mInvoked) {
   mJSInstance.invokeCallback(mCallbackId, Arguments.fromJavaArgs(args));
   mInvoked = true;
}

ist so etwas nicht genug?

@hyochan Entschuldigung, ich hatte gestern keine Zeit, mir das anzuschauen, hoffentlich kann ich bald einen Blick darauf werfen

@ Ilario17 Es ist wahrscheinlich zu vorliegt. Um fair zu sein, sollten wir diese Methode nicht mehrmals aufrufen

edit: ah, das Problem tritt auf, wenn onBillingSetupFinished mehr als einmal vorkommt. In ensureConnection wir den Listener entfernen, wenn wir fertig sind (dh wenn wir callback.run() anrufen oder das abgegebene Versprechen ablehnen). Sollte eine einfache PR sein, wenn jemand Lust auf freies Karma hat! Ansonsten werde ich versuchen, es bald zu erreichen

@LinusU Meinst du also onBillingSetupFinished , wir sollten die billingClientStateListener entfernen? Würde jemand dieses ausprobieren, um ein Teil von uns zu sein?

Wenn Sie eine schnelle und schmutzige Lösung wünschen, würde ich dieser Funktion eine lokale Variable hinzufügen, didCallCallback = false . Bewachen Sie dann den Anruf auf callback.run() hinter if (didCallCallback) { didCallCallback = true; callback.run() } .

Eine sauberere Lösung wäre einfach, den Hörer nach dem ersten Anruf insgesamt abzumelden ...

Log.d(TAG, "billing client ready");
callback.run();
//deregister the listener here?

Ich habe gerade 2.4.0-beta2 , um dies zu beheben. Bitte versuche.

@ Hyochan Ich werde diese neue Version versuchen

Bitte versuchen Sie es mit 2.4.0-beta3, da Beta2 ein Regressionsproblem hatte.

@hyochan nach dem Update ist der Fehler immer noch da :(

@ Ilario17 Was ist mit 2.4.0-beta5 ? Da ich dies auf meiner Seite nicht reproduzieren kann, brauche ich Ihren Test :(

@hyochan warum nicht einfach den Listener entfernen, wie @LinusU sagte?

@ Ilario17 Ich war neugierig, ob das die richtige Lösung ist. Ich bin auch der Meinung, dass onBillingServiceDisconnected benachrichtigt werden sollte. Sie können versuchen, es zu entfernen und dies an Ihrer Seite zu testen und zu sehen, ob es funktioniert.

Ich weiß nicht, ob dies damit zusammenhängt, aber ich bekomme diesen Absturz in 2.4.0-beta5. Es ist einfach, im Emulator zu reproduzieren:
Ich montiere die Komponente dort, wo IAP geladen wird, hebe sie ab und montiere sie dann erneut, Boom Crash.
BEARBEITEN: Ich habe ein Downgrade auf dieses Commit durchgeführt und es stürzt nicht mehr ab https://github.com/dooboolab/react-native-iap/commit/2db337ac770a93508507ec046f31085ddbb346fb

Attempt to invoke virtual method 'void com.android.billingclient.api.BillingClient.querySkuDetailsAsync(com.android.billingclient.api.SkuDetailsParams, com.android.billingclient.api.SkuDetailsResponseListener)' on a null object reference
run
    RNIapModule.java:223
ensureConnection
    RNIapModule.java:113
getItemsByType
    RNIapModule.java:218
invoke
    Method.java
invoke
    JavaMethodWrapper.java:372
invoke
    JavaModuleWrapper.java:160
run
    NativeRunnable.java
handleCallback
    Handler.java:789
dispatchMessage
    Handler.java:98
dispatchMessage
    MessageQueueThreadHandler.java:29
loop
    Looper.java:164
run
    MessageQueueThreadImpl.java:192
run
    Thread.java:764

Hier ist der Code, der den Absturz beim 2. Mount (2.4.0-beta5) verursacht:

componentDidMount() {
    this.loadIAPProducts()
}

componentWillUnmount() {
    RNIap.endConnection();
}

loadIAPProducts = async () => {
    const itemSkus = ['XXXX_id']

    const result = await RNIap.initConnection();
    if(result) {
      try {
        const products = await RNIap.getProducts(itemSkus);
        if (products) {
          this.setState({ iapProducts: products })
        }
      } catch (err) {
        //console.log(err); // standardized err.code and err.message available
      }

      this.restoreIAPPurchases()
    }
  }

  restoreIAPPurchases = async () => {
    try {
      const purchases = await RNIap.getAvailablePurchases()
      if(purchases) {
        purchases.forEach(purchase => {
          if (purchase.productId === 'XXXX_id') {
            try {
              RNIap.consumePurchase(purchase.purchaseToken);
            } catch(err) {

            }
          }
        })
      }
    } catch (err) {
      //console.log(err)
    }
  }

@ rom1k Nun, das würde im Android Emulator nicht funktionieren. Bitte versuchen Sie es mit einem echten Gerät.

@hyochan Ich

Für 2.4.0-beta3 unter Android wird beim Aufrufen von getProducts die Fehlermeldung "Kauf mit Code: 0 (OK) fehlgeschlagen" angezeigt. Beta 4 und 5 führen tatsächlich zum Absturz. Ich habe ein Downgrade auf 2.3.5 durchgeführt und es funktioniert einwandfrei, aber ich benötige die Fehlerbehebungen für den iOS-Listener in der Beta-Version 2.4.0

`` `
componentDidMount () {
this.getProductDetails ();
}}

getProductDetails = async () => {
    try {
        await RNIap.initConnection();
        const details = await RNIap.getProducts(products);
        this.setState({
            title: details[0].title,
            description: details[0].description,
            price: details[0].localizedPrice,
            loading: false
        });
    } catch (err) {
        console.log(err.message)
    }
};

Könnten Sie Beta5 und Comeback versuchen? Da diese Version einen Fehler aufwies, habe ich sie schnell behoben

@hyochan @LinusU mit Version 2.4.0-beta5 ist der Fehler immer noch da.

Ich habe einige Informationen, die für diese Diskussion relevant sind.

Unter 2.4.0-beta5 wird der folgende Fehler angezeigt

Attempt to invoke virtual method void com.android.billingclient.api.BillingClient.querySkuDetailsAsync(...) on a null object reference

Zeigen auf RNIapModule.java Zeile 223. Dies impliziert, dass mBillingClient hier unerwartet null ist.

So reproduzieren Sie : Mounten Sie eine reaktionsnative Komponente, die RNIap.getProducts() auf componentDidMount und RNIap.endConnection() auf componentWillUnmount aufruft. Hängen Sie die Komponente aus und montieren Sie sie erneut. Der obige Fehler sollte auftreten.

Die Variable clientReady wird verwendet, um zu verfolgen, ob die Einrichtung des Abrechnungsclients abgeschlossen wurde, indem sie im onBillingServiceDisconnected() -Rückruf auf false . Aber mBillingClient selbst wird sofort auf null gesetzt, wenn endConnection() aufgerufen wird. Dies ist eine Nichtübereinstimmung. Es ist möglich, dass clientReady auf true gesetzt bleibt, selbst wenn mBillingClient null ist. Ich glaube, das passiert, zumindest wegen meines Fehlers. Es scheint, dass etwas verhindert, dass onBillingServiceDisconnected() aufgerufen wird.

Ich kann bestätigen, dass ich nicht wie erwartet "billing client disconnected" in logcat beim Abmelden erhalte, sodass onBillingServiceDisconnected() in der Tat nicht aufgerufen wird.

Mögliche Lösung : Setzen Sie clientReady = false innerhalb der endConnection() -Methode (z. B. nach Zeile 179). Ich habe dies auf dem Gerät getestet und es scheint zu funktionieren. Das mehrmalige erneute Mounten der In-App-Kaufkomponente scheint keine Fehler oder Abstürze zu verursachen. Überlegen Sie auch, ob mBillingClient auf null gesetzt werden muss. Ich habe hier keine Erfahrung, kann ich also nicht sagen, aber es scheint ein wenig seltsam. Ich sehe auch keine anderen Projekte auf Github, die den Abrechnungsclient in diesem Rückruf auf Null setzen.

@ mitchellmcm27 Danke für deinen Fang. Das ist sehr vielversprechend und ich stimme Ihnen zu. Es war schwierig für mich, das Problem ohne minimale Reproduktion zu beheben. Außerdem möchte ich die Probleme gemeinsam lösen.

Bitte geben Sie uns PR wenn Sie daran denken, dieses Problem zu beheben.

Freundliche Grüße.

Ich habe 2.4.0-beta6 in der neuesten Version meiner App mit einigen tausend Upgrades veröffentlicht. Noch keine Abstürze 👍

Klingt gut. Vielen Dank für das Update! Ich werde dieses Problem vorerst schließen.

Ich habe bereits einen Absturz mit dem gleichen Stacktrace, aber viel weniger als zuvor.


java.lang.RuntimeException: 
  at com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
  at com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
  at com.dooboolab.RNIap.RNIapModule$4.run (RNIapModule.java:155)
  at com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished (RNIapModule.java:124)
  at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
  at android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:1658)
  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run (LoadedApk.java:1687)
  at android.os.Handler.handleCallback (Handler.java:789)
  at android.os.Handler.dispatchMessage (Handler.java:98)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6944)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

Auch immer noch den gleichen Stacktrace auf 2.4.0-Beta6

Ich denke, dieser Fehler sollte wieder geöffnet werden.

schermata 2019-01-11 alle 10 51 20

120 Absturz in weniger als 24 Stunden.

Ich bin nicht sicher, ob die letzten Änderungen keine eigenen Probleme verursacht haben, z. B. wenn mBillingClient nicht null ist, aber noch nicht fertig ist, überschreibt die Funktion ensureConnection einfach mBillingClient mit einem neuen Kunden, der den alten wegwirft 🤔

Ich möchte wissen, in welcher Version dieser Fehler angezeigt wurde, damit ich auf eine stabile Version zurücksetzen kann.

Ich denke auch, dass das Thema wieder geöffnet werden sollte. Das ursprüngliche Problem hatte mit dem Rückruf zu tun, und die Korrekturen dafür zeigten den Fehler "Null-Objektreferenz". Obwohl letzteres möglicherweise behoben wurde (ich stimme @LinusU zu, dass es dort möglicherweise mehr Probleme gibt), beschäftigen wir uns immer noch mit dem ursprünglichen Problem.

Ich habe auch ein paar Abstürze im Zusammenhang mit dem Rückruf in Beta6 bekommen.

Ich habe das wieder geöffnet. Hoffe, jemand kann PR dafür geben.

Weißt du, wann dies eingeführt wurde? Ich würde mehr als glücklich sein, zurück zu rollen.

Ich kann bestätigen, dass die Abstürze sowohl in Beta6 als auch in 2.3.23 unter Android vorliegen. Ziemlich einfach nach diesem [1] Kommentar neu zu erstellen.

Bearbeiten: Jetzt, da ich zu Hause bin, debugge ich in den nativen Android-Code für Beta6. Falls dies hilfreich ist, ist dies der Fall (zumindest in meiner App, die getAvailablePurchases aufruft):

  1. getAvailableItemsByType für "inapp" wird noch ohne das mBillingClient-Setup aufgerufen.
  2. Der Abrechnungsclient wird eingerichtet, das im Listener onBillingSetupFinished wird aufgerufen und der Rückruf (Promise) wird verbraucht (aufgelöst). Der Listener existiert noch.
  3. getAvailableItemsByType für "subs" wird mit dem mBillingClient-Setup aufgerufen. Der neue Rückruf (Promise) wird verbraucht (gelöst).
  4. Beenden Sie den Play Store-Dienst - onServiceDisconnected in BillingClientImpl wird aufgerufen, der Listener aus Teil 1 übernimmt dies. Ein neuer Dienst wird gestartet, und der Listener aus Teil 1 verarbeitet das onBillingSetupFinished und versucht, den Rückruf (Promise) aus Schritt 1 zu verwenden, der erneut aufgerufen wird.

Ich werde damit experimentieren, den Hörer auszuschalten, sobald er nicht mehr benötigt wird.

[1]
https://github.com/googlesamples/android-play-billing/issues/45#issuecomment -324466519

Ich habe # 379 zusammengeführt und auf beta8 . Bitte versuchen Sie das.

Ist das in der neuesten Version behoben? Ist ein Upgrade auf die neueste Version sicher?

@hyochan dieses Problem erscheint immer noch in 3.0.0-rc-2 irgendeine Idee?

java.lang.RuntimeException
com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished

java.lang.RuntimeException: 
  at com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
  at com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
  at com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished (RNIapModule.java:129)
  at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection$1.run (BillingClientImpl.java:1518)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:7325)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)

@fokoz Könnten Sie 3.0.0-rc-4 versuchen? Es wird perfekt funktionieren (hoffentlich).

@hyochan Wenn ich try catch dieser Laufzeitfehler nicht auf. Ich denke, rc-4 sollte dies beheben.
Danke !

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen