in-app billing doesn't work: “IAB Helper is not set up”

前端 未结 5 1836
粉色の甜心
粉色の甜心 2020-12-08 19:55

I tried to include in-app billing in my app and for the purpose of testing, based the whole procedure on the \"TrivialDrive\" example for version 3 of in-app billing (and im

5条回答
  •  醉梦人生
    2020-12-08 20:43

    The fundamental problem is that startRegistered() is being invoked in direct response to a UI user click, whereas the setup of your IabHelper object is triggered asynchronously, and so cannot be known to have completed until an asynchronous response is received via onIabSetupFinished().

    Your startRegistered() method is triggered by a user click, and that calls launchPurchaseFlow(), which in turn requires that the IabHelper object has already completed setup, but if the user clicks to trigger a purchase before that confirmation is received (either because setup failed or because the user is exceptionally quick on the draw), then setup will not have been completed, and launchPurchaseFlow() will report the error that you're seeing. In the case of your logcat, the delay is 14 seconds, which would usually be enough time, but...maybe not in this case. Or, maybe something went wrong and you never would have connected no matter how long you had waited.

    In your logcat, there's no message indicating "Billing service connected," which is one of the first things that must happen if your setup is to complete. Since that does not occur, you are also not seeing any message (either of success or of failure) from onIabSetupFinished().

    This is tricky stuff because of the asynchronous responses required. One approach would be to disable the button used to trigger a purchase until your onIabSetupFinished() returns with success. This would prevent the triggering of the purchase until the IabHelper object had been successfully set up. Of course, if setup fails, you'll have a non-functioning button, but at least you can tell the user what's up (by putting up a message that indicates you're waiting for setup to complete - e.g., as part of the button text).

    Even then, once your purchase is initiated and the payment dialog appears to the user, there's the possibility of your app going through an onStop() cycle that flushes your app from memory while the user is pondering her purchase (since the purchase dialog is part of Google Play, not part of your app, and the OS may require memory to run it, and that memory may be obtained by stopping your app). That would destroy your IabHelper() object, which would then have to be created and asynchronously set up again. And again, since that is be triggered asynchronously in your onCreate() method, onActivityResult() may be invoked by the Google Play service to report the user's purchase action before the IabHelper object's setup has completed, and since in onActivityResult() you will need to use your IabHelper instance, this could result in an error. It seems that you have to be prepared for anything.

    This should give you the flavor of what you're dealing with. IAB is difficult for exactly these reasons - multiple threads of asynchronous stuff (e.g., setup vs. purchases vs. Android OS actions that stop your app to grab memory for use by, quite possibly, the very Google Play app purchase operation for which your app is waiting to obtain the results of the purchase). A lot of what gets implemented (including by the TrivialDrive sample) is flaky because it implicitly relies upon your app staying in memory when in fact it might get recycled, or because it relies upon one leg of a race condition (e.g. setup) completing before another leg (e.g., purchase launch) does, and so on.

提交回复
热议问题