Task API

Task — это асинхронная задача, возвращающая ошибку или значение в соответствующих callback (onFailure, onSuccess).

В качестве примера реализации используется метод SDK оплаты getProducts(). 

Обработка результата выполнения Task

Методы, выполняемые асинхронно, возвращают Task<T>. К примеру, RuStoreBillingClient.getProducts() возвращает Task<ProductsResponse>. Это означает, что Task вернет ProductsResponse, если выполнение метода было успешно:

val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()

Чтобы получить результат успешного выполнения метода, добавьте callback OnSuccessListener к Task:

val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()
task.addOnSuccessListener {
    // Process success
}

Чтобы получить ошибку выполнения, добавьте callback OnFailureListener к Task:

val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()
task.addOnFailureListener {
    // Process error
}

Если необходимо получить и успешный результат, и ошибку, добавьте OnCompleteListener к Task:

val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()
task.addOnCompleteListener(object : OnCompleteListener<ProductsResponse> {
    override fun onFailure(throwable: Throwable) {
        // Process Error
    }
 
    override fun onSuccess(result: ProductsResponse) {
        // Process success
    }
})

Многопоточность

Callback, добавленные к Task, выполняются на главном потоке приложения. Если callback необходимо выполнить в другом потоке, передайте свой Executor в метод добавления callback.

Добавление executor через корутины:

val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()
task.addOnCompleteListener(Dispatchers.IO.asExecutor(), object : OnCompleteListener<ProductsResponse> {
    override fun onFailure(throwable: Throwable) {
        // Process Error
    }
 
    override fun onSuccess(result: ProductsResponse) {
        // Process success
    }
})

Синхронное выполнение

Если ваш код уже выполняется в рабочем потоке и вам необходимо получить результат синхронно, вы можете использовать task.await():

try {
    val task: Task<ProductsResponse> = RuStoreBillingClient.products.getProducts()
    task.await()
} catch (e: CancellationException) {
    // Process error
}

Использовать метод await() рекомендуется только после следующих версий SDK:

  • SDK для in-app платежей — billingclient:1.1.1.
  • SDK для подключения пуш-уведомлений — pushclient:0.1.8.
  • SDK для подключения отзывов и оценок — review:0.1.6.
  • SDK для обновления приложения — appupdate:0.1.1.

Вызов метода await() для SDK более ранних версий может приводить к увеличенному потреблению батареи!

Обработка Task API через корутины

Для обработки Task в корутине можно использовать следующий код:

suspend fun <T> Task<T>.wrapInCoroutine(): Result<T> {
    return suspendCancellableCoroutine { continuation ->
        addOnCompleteListener(object : OnCompleteListener<T> {
 
            override fun onSuccess(result: T) {
                if (continuation.isActive) {
                    continuation.resume(Result.success(result))
                }
            }
 
            override fun onFailure(throwable: Throwable) {
                if (continuation.isActive) {
                    continuation.resume(Result.failure(throwable))
                }
            }
        })
 
        continuation.invokeOnCancellation {
            cancel()
        }
    }
}
Обновлено 23 июня 2023 г.
Was this information helpful?