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() } } } |