I have setup In-App Billing for the first time using the new v3 API. It is working correctly on my devices but I have received a lot of error reports from other users.
O
I believe that there are still two bugs in the Android code, which explains why you still see the error. Notice that the call stack is on a stand-alone thread. But the code that sets mSetupDone (IabHelper) to true executes on the main UI thread. Java does not guarantee that data changed by one thread will be visible to the other thread due to CPU caching unless you declare the variable with the volatile keyword. Thus it is possible that it was setup (mSetupDone == true), but that the new value of mSetupDone is cached on UI thread, not yet visible to this thread in your call stack. So that thread still sees mSetupDone == false.
I tried to fix this by declaring mSetupDone with volatile, and also every other non-final field of IabHelper just to be safe.
Now the other problem is the .dispose() function. It does not stop the ongoing threads. This means that it can set mSetupDone to false while one of the worker threads is running. If you look at queryInventoryAsync(), you will see it does check that mSetupDone is true. And based on your call stack, it did get past that. Then it crashed later with mSetupDone == false. Only way that could happen is if dispose() were called while your thread was in flight. Fix is that dispose() needs to signal threads to just silently bail out instead of continuing and throwing errors when it sees mSetupDone == false. This also prevents yet another problem with IabHelper where disposed instances call listener callbacks even after being disposed! It's a bit complicated to explain line by line here, but hopefully thus gets you pointed in the right direction.