Перейти к основному содержимому

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() блокирует поток, в котором выполняется. Стоит использовать корутины, если вы пишите на Kotlin или вызывать метод в фоновом потоке, если используете языки где нет корутин.

предупреждение

Использовать метод await() рекомендуется только после следующих версий SDK: SDK для in-app платежей - billingclient:1.1.1 SDK для подключения push-уведомлений - 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()
}
}
}