React-native-iap: Android вылетает на многих устройствах после выпуска

Созданный на 9 нояб. 2018  ·  45Комментарии  ·  Источник: dooboolab/react-native-iap

Версия react-native-iap

"react-native": "0.55.4"
"react-native-iap": "^ 2.3.2"

Платформы, на которых вы столкнулись с ошибкой (IOS или Android или оба?)

Android

Ожидаемое поведение

Пожалуйста, помогите мне, мне нужно немедленно это исправить. Потому что уже есть + 2к пользователей

Фактическое поведение

Приложение вылетает из-за rniap на многих устройствах. В игровой консоли я увидел, что эта ошибка вызывает сбой:
java.lang.RuntimeException:

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

Протестированная среда (Эмулятор? Настоящее устройство?)

вот отчет с игровой консоли:
https://ibb.co/gDxZQA

Шаги по воспроизведению поведения

Не знаю, что делать, я использовал rniap, как в примере.
в componentDidMount:
пытаться {
const result = ждать RNIap.initConnection ();
} catch (err) {
console.log (ошибка);
}
в componentWillUnmount:
RNIap.endConnection ();

🐛 bug 🤖 android

Самый полезный комментарий

@hyochan, извините, вчера не было времени взглянуть на это, надеюсь, я смогу взглянуть в ближайшее время

@ Ilario17 Вероятно, чтобы

edit: ах, проблема возникает, когда onBillingSetupFinished встречается более одного раза. В ensureConnection нам нужно удалить слушателя, когда мы закончим (то есть, когда мы вызываем callback.run() или отклоняем переданное обещание). Должен быть легкий пиар, если кто-то хочет получить бесплатную карму! В противном случае я постараюсь добраться до него в ближайшее время

Все 45 Комментарий

Не могли бы вы попробовать нашу последнюю версию 2.3.19 и вернуться?

Я не могу. Потому что это была непосредственная ситуация. Итак, я изменил пакет iap. Теперь в + 3к юзеров вылетов нет. Но спасибо. Я попробую это сделать в своем следующем проекте.

Привет, можешь снова открыть эту проблему? У меня такая же проблема, но я использую версию 2.3.21

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

это мой 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 Не могли бы вы нам помочь? Почему callback.run() вылетает в выпуске? Должны ли мы проверить, является ли callback нулевым в ensureConnection ? Хм. это runtime exception .

Хммм, что здесь означает RuntimeException , больше нет информации? @hyochan, почему ты думаешь, что callback было null ? 🤔

@LinusU Спасибо за ваш отзыв. В настоящее время понятия не имею Я только что видел строку с проблемой ниже.
image

В RNIapModule.java строке 124,

callback.run();

Есть ли у вас еще идеи?

@LinusU Если вы не имеете ни малейшего представления об этом, я бы подумал о том, чтобы откатить его туда, где мы были раньше.

Хорошо, вот в чем проблема:

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

По какой-то причине мы вызываем обратный вызов более одного раза, это должно быть легко исправить!

@LinusU Отлично выглядит, потому что ты на трассе! Не могли бы вы дать нам PR за это?

Почему в этом методе есть исключение RuntimeException?

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

этого недостаточно?

@hyochan, извините, вчера не было времени взглянуть на это, надеюсь, я смогу взглянуть в ближайшее время

@ Ilario17 Вероятно, чтобы

edit: ах, проблема возникает, когда onBillingSetupFinished встречается более одного раза. В ensureConnection нам нужно удалить слушателя, когда мы закончим (то есть, когда мы вызываем callback.run() или отклоняем переданное обещание). Должен быть легкий пиар, если кто-то хочет получить бесплатную карму! В противном случае я постараюсь добраться до него в ближайшее время

@LinusU Так вы имеете в виду onBillingSetupFinished , мы должны удалить billingClientStateListener ? Может ли кто-нибудь попробовать это, чтобы стать частью нас?

Если вам нужно быстрое и грязное решение, я бы добавил к этой функции локальную переменную didCallCallback = false . Затем защитите вызов callback.run() за if (didCallCallback) { didCallCallback = true; callback.run() } .

Более чистым решением было бы просто полностью отменить регистрацию слушателя после первого вызова ...

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

Я только что выпустил 2.4.0-beta2 чтобы исправить это. Пожалуйста, попробуй.

@hyochan я попробую эту новую версию

Пожалуйста, попробуйте версию 2.4.0-beta3, так как в beta2 возникла проблема регресса.

@hyochan после обновления ошибка все еще есть :(

@ Ilario17 А как насчет 2.4.0-beta5 ? Поскольку я не могу воспроизвести это на своей стороне, мне нужен ваш тест :(

@hyochan, почему бы просто не удалить слушателя, как сказал @LinusU ?

@ Ilario17 Мне было любопытно, правильное ли это решение. Кроме того, я считаю, что нужно уведомить onBillingServiceDisconnected . Вы можете попробовать удалить его, проверить это на своей стороне и посмотреть, работает ли он.

Я не знаю, связано ли это, но я получаю этот сбой в 2.4.0-beta5. В эмуляторе легко воспроизвести:
Я монтирую компонент, где загружается IAP, размонтирую его, а затем снова монтирую, грохот сбой.
РЕДАКТИРОВАТЬ: я перешел на эту фиксацию, и она больше не дает сбоев 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

Вот код, который вызывает сбой при 2-м монтировании (2.4.0-beta5):

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 Ну, это не будет работать в эмуляторе Android. Пожалуйста, попробуйте на реальном устройстве.

@hyochan Я заметил, что версия 2.4.0-beta3 на 50% меньше вылетает, но все еще недостаточно

Для 2.4.0-beta3 на Android я получаю сообщение об ошибке «Покупка не удалась с кодом: 0 (OK)» только при вызове getProducts. бета 4 и 5 на самом деле вызывают сбой. Я понизил версию до 2.3.5, и она работает нормально, но мне нужны исправления ошибок прослушивателя ios в бета-версии 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)
    }
};

Не могли бы вы попробовать бета5 и вернуться? В этой версии была ошибка, поэтому я быстро исправил

@hyochan @LinusU с версией 2.4.0-beta5 ошибка все еще существует.

У меня есть некоторая информация, относящаяся к этому обсуждению.

В 2.4.0-beta5 я получаю следующую ошибку

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

указывает на RNIapModule.java строку 223. Это означает, что mBillingClient неожиданно оказался здесь null .

Для воспроизведения : смонтируйте компонент, поддерживающий реакцию, который вызывает RNIap.getProducts() для componentDidMount и RNIap.endConnection() для componentWillUnmount . Размонтируйте компонент и снова установите его. Вышеуказанная ошибка должна произойти.

Переменная clientReady используется для отслеживания того, завершена ли настройка биллингового клиента, путем установки для нее значения false в onBillingServiceDisconnected() . Но mBillingClient само обнуляется сразу после вызова endConnection() . Это несоответствие. clientReady может оставаться равным true , даже если mBillingClient имеет значение null. Я считаю, что это то, что происходит, по крайней мере, из-за моей ошибки. Похоже, что-то мешает вызвать onBillingServiceDisconnected() .

Я могу подтвердить, что я не получаю "billing client disconnected" в logcat при отключении, как ожидалось, поэтому onBillingServiceDisconnected() действительно не вызывается.

Возможное исправление : установите clientReady = false в методе endConnection() (например, после строки 179). Я тестировал это на устройстве, и, похоже, он работает. Повторное подключение компонента покупки в приложении несколько раз, похоже, не приводит к каким-либо ошибкам или сбоям. Также подумайте, нужно ли установить mBillingClient в ноль? У меня здесь нет никакого опыта, поэтому я не могу сказать, но это кажется немного странным. Я также не вижу других проектов на Github, обнуляющих биллинговый клиент в этом обратном вызове.

@ mitchellmcm27 Спасибо за ваш улов. Это очень многообещающе, и я согласен с вами. Мне было сложно решить проблему без минимального воспроизведения. Также хотелось бы вместе решать проблемы.

Пожалуйста, дайте нам PR если у вас есть какие-либо мысли по поводу решения этой проблемы.

С наилучшими пожеланиями.

Я выпустил 2.4.0-beta6 в последней версии своего приложения с несколькими тысячами обновлений. Вылетов пока нет 👍

Звучит здорово. Большое спасибо за исправление! А пока я закрою этот выпуск.

У меня уже был сбой с той же трассировкой стека, но намного меньше, чем раньше.


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)

Также все еще получается такая же трассировка стека на 2.4.0-beta6

Я думаю, что эту ошибку следует снова открыть.

schermata 2019-01-11 alle 10 51 20

120 аварий менее чем за 24 часа.

Я не уверен, что последние изменения не вызвали их собственных проблем, например, если mBillingClient не равно null, но еще не готово, функция ensureConnection просто перезапишет mBillingClient с новым клиентом, выбрасывая старого

Я хотел бы знать, какая версия начала показывать эту ошибку, чтобы я мог вернуться к стабильной версии.

Я тоже считаю, что этот вопрос следует снова открыть. Первоначальная проблема была связана с обратным вызовом, и исправления для этого выявили ошибку «ссылка на нулевой объект». Хотя последнее могло быть исправлено (я согласен с @LinusU, что там может быть больше проблем), мы все еще работаем над исходной проблемой.

У меня также было несколько сбоев, связанных с обратным вызовом в beta6.

Я снова открыл это. Надеюсь, кто-то может дать за это PR .

Вы, ребята, знаете, когда это было введено? Я был бы более чем счастлив откатиться назад.

Я могу подтвердить, что сбои существуют на бета6-версии, а также на 2.3.23 на Android. Согласно этому [1] комментарию, довольно легко воссоздать.

Изменить: теперь, когда я дома, я отлаживаю собственный код Android для beta6. Если это полезно, вот что происходит (по крайней мере, в моем приложении, вызывающем getAvailablePurchases):

  1. getAvailableItemsByType для inapp вызывается без настройки mBillingClient.
  2. Клиент выставления счетов настраивается, вызывается onBillingSetupFinished в прослушивателе, и обратный вызов (обещание) используется (разрешается). Слушатель все еще существует.
  3. getAvailableItemsByType для «подписок» вызывается с настройкой mBillingClient. новый обратный вызов (обещание) потребляется (разрешен).
  4. Убейте службу Play Store - вызывается onServiceDisconnected в BillingClientImpl, обработчик из части 1 обрабатывает его. Запускается новая служба, и слушатель из части 1 обрабатывает onBillingSetupFinished и пытается использовать обратный вызов (обещание) из первого шага, вызывается снова.

Я поэкспериментирую с отключением слушателя, если он больше не нужен.

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

Я объединил # 379 и выпустил beta8 . Пожалуйста, попробуйте это.

Это исправлено в последней версии? Безопасно ли обновляться до последней версии?

@hyochan эта проблема все еще появляется в 3.0.0-rc-2, есть идеи?

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 Не могли бы вы попробовать 3.0.0-rc-4 ? Он будет работать отлично (надеюсь).

@hyochan Если я использую try catch этой ошибки времени выполнения не будет, я думаю, что rc-4 должен решить эту проблему.
Спасибо !

Была ли эта страница полезной?
0 / 5 - 0 рейтинги