PurchasingObserver lifecycle / no unregisterObserver()
I don't see any documentation on the PurchasingObserver lifecycle - is there any? The docs encourage calling registerObserver() in Acitity.onStart(), but there is no unregisterObserver(). In tests with multiple observers, my tests show that the last observer added is the one that receives the callback. One use case here involves multiple activities and background processing. Say, for example, I start a background process that updates a list of products from my web service, and then calls initiateItemDataRequest() to get SKU information from Amazon for that list. In theory, this all runs pretty quickly, but there's always the chance that either the call to my web service or the call to Amazon IAP could take long enough where the user could exit the app while it's running. Once they exit, there's no guarantee that they will come back to the Activity from which they left. If they come back to the app through a different Activity, and that activity.onStart() registers a new PurchasingObserver, then there is a race condition and the response to the originally registered PurchasingObserver may never get called. To avoid that particular race condition (no matter how small the likelihood), I'm thinking of registering the PurchasingObserver in the Application instead of any single Activity. But that differs from the suggestion in the docs. Is it a bad idea? If so, why? Also, any general docs on PurchasingObserver lifecycle would be helpful. Thanks, iamkirk
Application Class is used for declaring Global Variables, and is commonly used as a single instance and is visible for all modules in the application. you can write the common methods in this class. The constructor of the application class is called once in the application life cycle in the beginning . Using in the activity is suggested as of below points: When the application resumes the application checks which customer is signed in and get all the IAP items and keep it common all the across the devices of the user. On Start of the activity, we need to register to the observer and all callback will be on the observer which is registered to the activity. onPurchaseUpdatesResponse is invoked once the call from initiatePurchaseUpdatesRequest is completed.On a successful response, a response object is passed which contains the request id, request status, a set of previously purchased receipts, a set of revoked skus, and the next offset if applicable. If a user downloads your application to another device, this call is used to sync up this device with all the user's purchases. So as above API can be used, every time the activity starts up, if the application is abruptly exited there would be on issue.
Thanks for the reply and the further details on Application lifecycle as well as a typical Activity use case. I'm not sure I heard the answer to my question, though, and I think I may need to clarify. When I said "exit" the app, I didn't mean a force quit of the app, I meant simply that the user stops the app and moves it to the background. With that clarification, maybe it would also help if I asked the question a bit differently: * What are the downsides to having a single PurchasingObserver at the application level? Although it exposes us to the usual concerns around global state in the app, it seems to match more closely how the Amazon library is using the PurchasingObserver that's registered. * [new, but related questions which may help guide the answer to the original one]: when is a registered PurchasingObserver eligible for garbage collection? When is the referenced Context (that's passed into the constructor) eligible for garbage collection? Put more simply, does the Amazon library hold strong or weak references to the PurchasingObserver and the Context?
Hi Iamkirk, Thank you for your post. There is no harm of having a single PurchasingObserver at the application level. Having that, you could always call IAP methods to PurchasingManager from a storefront activity and after getting response in observer you should be able to broadcast events to notify the target activity to take UI actions. This way you should be able to avoid race condition as you mentioned above. This is true that there is no unregister call available to deregister the current observer from ParchasingManager. But you could call register with a null value to effect a deregister of the listener. After you do it, there will be no reference to that object from IAP SDK. So in next GC cycle it is supposed to be garbage collected. Hope this helps.