Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android kotlin task to be executed using coroutines

As an example, I'm using FusedLocationProviderClient to access the current location, which returns a task which callback will eventually return the location. The method looks something like follows:

fun getLocation(callback: MyCallback){
    val flpc = LocationServices.getFusedLocationProviderClient(it)
    flpc.lastLocation.addOnSuccessListener {
        callback.onLocation(it)
    }
}

Is it possible to transform this so that I can use corroutines to suspend this function and wait for the task returned by flpc.lastLocation so I can return it in this method and this way get rid of that callback? For example something like this:

suspend fun getLocation(): Location? =
    withContext(Dispachers.IO){
        val flpc = LocationServices.getFusedLocationProviderClient(it)
        return@withContext flpc.lastLocation.result()
    }

My question is if there is something around coroutines where I can return the result of a Task (in this example, a Task<Location>)

Thanks in advance!

like image 996
IIRed-DeathII Avatar asked Dec 10 '19 14:12

IIRed-DeathII


People also ask

How do coroutines operate long running tasks?

Manage long-running tasks Coroutines build upon regular functions by adding two operations to handle long-running tasks. In addition to invoke (or call ) and return , coroutines add suspend and resume : suspend pauses the execution of the current coroutine, saving all local variables.

What is Kotlin coroutines used for?

A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.

How do I use LiveData with coroutines?

ViewModel + LiveData You could use a MutableLiveData like so: But, since you will be exposing this result to your view, you can save some typing by using the liveData coroutine builder which launches a coroutine and lets you expose results through an immutable LiveData. You use emit() to send updates to it.

What is the purpose of coroutines in Android?

Coroutine Scope A CoroutineScope keeps track of any coroutine it creates using the builder functions launch or async . It provides the ability to cancel a coroutine at any point in time. The scope is nothing but a lifespan. A coroutine cannot be launched without scope.


1 Answers

The kotlinx-coroutines-play-services library has a Task<T>.await(): T helper.

import kotlinx.coroutines.tasks.await

suspend fun getLocation(): Location? = 
    LocationServices.getFusedLocationProviderClient(context).lastLocation.await()

Alternatively take a look at Blocking Tasks

It would be used the next way:

suspend fun getLocation(): Location? =
    withContext(Dispachers.IO){
        val flpc = LocationServices.getFusedLocationProviderClient(context)
        try{
            return@withContext Tasks.await(flpc.lastLocation)
        catch(ex: Exception){
            ex.printStackTrace()
        }
        return@withContext null
    }

Just to add to this example, for completion purposes, the call to getLocation() would be done the next way:

coroutineScope.launch(Dispatchers.Main) {
    val location = LocationReceiver.getLocation(context)
    ...
}

However this negates the benefits of coroutines by not leveraging the available callback and blocking a thread on the IO dispatcher and should not be used if the alternative is available.

like image 85
Kiskae Avatar answered Oct 25 '22 23:10

Kiskae