作为示例,我使用FusedLocationProviderClient访问当前位置,它返回一个任务,回调将最终返回该位置。该方法如下所示:
fun getLocation(callback: MyCallback){
val flpc = LocationServices.getFusedLocationProviderClient(it)
flpc.lastLocation.addOnSuccessListener {
callback.onLocation(it)
}
}
是否可以对此进行转换,以便可以使用例程来挂起此函数并等待flpc.lastLocation
返回的任务,以便可以用此方法将其返回,从而摆脱该回调?例如这样的东西:
suspend fun getLocation(): Location? =
withContext(Dispachers.IO){
val flpc = LocationServices.getFusedLocationProviderClient(it)
return@withContext flpc.lastLocation.result()
}
我的问题是,协程周围是否有东西可以返回Task
(在此示例中为Task<Location>
)的结果
谢谢!
答案 0 :(得分:1)
kotlinx-coroutines-play-services
库有一个Task<T>.await(): T
帮助器。
import kotlinx.coroutines.tasks.await
suspend fun getLocation(): Location? =
LocationServices.getFusedLocationProviderClient(context).lastLocation.await()
或者看看Blocking Tasks
它将以另一种方式使用:
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
}
仅出于示例目的,添加到此示例中,将以以下方式完成对getLocation()
的调用:
coroutineScope.launch(Dispatchers.Main) {
val location = LocationReceiver.getLocation(context)
...
}
但是,这通过不利用可用的回调并阻塞IO调度程序上的线程而否定了协程的好处,如果有可用的替代方法,则不应使用。