I'm setting up an interface to work with the Google Play Billing Library. I query subscription products with querySkuDetailsAsync and then I cycle through the products returned so I can enable purchase buttons.
This is the script I'm using
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
if (!list.isEmpty()) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getSku().equals("core_monthly")) {
monthlyDetails = list.get(i);
} else if (list.get(i).getSku().equals("core_annual")) {
annualDetails = list.get(i);
}
}
monthlySubscribe.setEnabled(true);
annualSubscribe.setEnabled(true);
monthlySubscribe.setText("Monthly Subscription");
annualSubscribe.setText("Annual Subscription");
} else {
Toast.makeText(getActivity(), "There was a problem getting available plans", Toast.LENGTH_SHORT);
}
}
});
The problem is that setText() the button texts are never updated. How can I update the button names and enable them after I get the products?
The reason why .setText()
doesn't work is because billingClient
method is called in a background thread
, as your log shows: Thread: PlayBillingLibrary-2
. Anything related to the UI
must be called in the main thread
.
To solve this you have to do something like this:
Add this method to your project:
private Handler findUiHandler() {
return new Handler(Looper.getMainLooper());
}
And then, whenever you want to update the UI
and the thread isn't main thread
, call your code like this:
findUiHandler().post(() -> {
//here is the code that needs to be executed on the main thread
monthlySubscribe.setEnabled(true);
annualSubscribe.setEnabled(true);
monthlySubscribe.setText("Monthly Subscription");
annualSubscribe.setText("Annual Subscription");
});