Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do the kotlin extension functions in com.android.billingclient:billing-ktx dispatch to Dispatchers.IO internally?

Reading the documentation for the billing client, there is a section entitled Querying with Kotlin extensions. The example shown includes a dispatch to Dispatchers.IO like this:

val productDetailsResult = withContext(Dispatchers.IO) {
    billingClient.queryProductDetails(params.build())
}

The withContext is shown on other suspending functions as well. queryProductDetails in the ktx lib and the others are all suspending functions. Why do the docs include withContext? I can't imagine the purpose of making a suspending function that just blocked the thread, it should internally dispatch to Dispatchers.IO in my opinion, rendering the withContext calls in the example code superfluous.

Is my assessment correct, can I omit the withContext blocks without blocking the Main thread (assuming the calling context is on Dispatchers.Main)? I wasn't able to determine what it was doing with the debugger, and there doesn't seem to be any documentation on the extension functions.

What I want to write is just:

val productDetailsResult = billingClient.queryProductDetails(params.build())
like image 649
Steve M Avatar asked Oct 15 '25 15:10

Steve M


1 Answers

The decompiled Java code of queryProductDetails extension function looks like the following:

   @Nullable
   @RecentlyNonNull
   public static final Object queryProductDetails(@RecentlyNonNull BillingClient $this$queryProductDetails, @RecentlyNonNull QueryProductDetailsParams params, @RecentlyNonNull Continuation $completion) {
      final CompletableDeferred var3 = CompletableDeferredKt.CompletableDeferred$default((Job)null, 1, (Object)null);
      ProductDetailsResponseListener var4 = new ProductDetailsResponseListener() {
         public final void onProductDetailsResponse(BillingResult billingResult, List productDetailsList) {
            Intrinsics.checkNotNullExpressionValue(billingResult, "billingResult");
            ProductDetailsResult var3x = new ProductDetailsResult(billingResult, productDetailsList);
            var3.complete(var3x);
         }
      };
      $this$queryProductDetails.queryProductDetailsAsync(params, var4);
      return var3.await($completion);
   }

We can see that it uses queryProductDetailsAsync under the hood, so it runs asynchronously. Therefore we can conclude that the call is not blocking and we don't need to wrap billingClient.queryProductDetails(params.build()) into withContext(Dispatchers.IO):

val productDetailsResult = billingClient.queryProductDetails(params.build())
like image 200
Sergey Avatar answered Oct 17 '25 03:10

Sergey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!