Some time ago, I’ve added in app purchases to a Flutter app (Android and iOS) by happily copy&pasting the code from the code lab.
It’s working in production. However, all out of a sudden, running the Android build from VS Code, prints the following two messages in rapid succession:
W/BillingClient(25973): Billing service disconnected.
D/InAppPurchasePlugin(25973): Tried to call onBillingSetupFinished multiple times.
After the messages are logged hundreds of times, the following DeadObjectException
occasionally joins in:
W/BillingClient(25973): Exception while checking if billing is supported; try to reconnect
W/BillingClient(25973): android.os.DeadObjectException
W/BillingClient(25973): at android.os.BinderProxy.transactNative(Native Method)
W/BillingClient(25973): at android.os.BinderProxy.transact(BinderProxy.java:595)
W/BillingClient(25973): at com.google.android.gms.internal.play_billing.zzh.zzo(com.android.billingclient:billing@@6.0.1:2)
W/BillingClient(25973): at com.google.android.gms.internal.play_billing.zzc.zzq(com.android.billingclient:billing@@6.0.1:5)
W/BillingClient(25973): at com.android.billingclient.api.zzaf.zza(com.android.billingclient:billing@@6.0.1:13)
W/BillingClient(25973): at com.android.billingclient.api.zzac.call(Unknown Source:2)
W/BillingClient(25973): at java.util.concurrent.FutureTask.run(FutureTask.java:264)
W/BillingClient(25973): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
W/BillingClient(25973): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
W/BillingClient(25973): at java.lang.Thread.run(Thread.java:1012)
Problem with these messages is that the device runs hot and the animations become jerky, indicating that either BillingClient
or InAppPurchasePlugin
is busy in an endless loop.
Now the short question is, what’s causing this? And how can it be fixed?
Where it happens:
The code lab recommends to create an IAPConnection
class looking like:
// Gives the option to override in tests.
class IAPConnection {
static InAppPurchase? _instance;
static set instance(InAppPurchase value) {
_instance = value;
}
static InAppPurchase get instance {
_instance ??= InAppPurchase.instance;
return _instance!;
}
}
Shortly after InAppPurchase.instance;
is accessed for the first time, the messages start to show up. Even if in_app_purchase’s api is otherwise unused.
What’s also interesting is that IAPConnection.instance.purchaseStream
‘s onError()
callback isn’t called.
Beside that, in app purchases are working just fine in production and even in debug mode, purchases are properly restored before the messages start to show up.
It happens on a physical Android 13 device with in_app_purchase package 3.1.5 to 3.1.10 and Flutter 3.13.6.
Any ideas on what causes this or how to workaround or fix it are very much appreciated. Thank you.
2
Answers
I’m in the same boat, out of the blue suddenly this error occurs on a physical Android device using flutter in_app_purchase: ^3.1.10.
Strangely it used to work before some time…
EDIT: So I found the source of the problem in my case was that I added code to restore purchases in the initialization phase
The last line that is commented out caused the problem.
You should open a record on issue tracker, this is Google’s problem 100%.
By the way you can trigger this by running your app and then changing the system language a couple of times.
I tried to open an issue myself, twice, but it just won’t appear.