Ili*_*hin 4 android kotlin rx-java2 kotlin-coroutines
我正在尝试将带有 rxjava 链的交互器重写为 kotlin 流。在 LocationHandlerImpl 中,我使用 LocationService 来获取我的当前位置。在 addOnSuccessListener 和 addOnFailureListener 我发出我的模型但有错误:
“只能在协程体内调用暂停函数”。我做错了吗?但是我可以在侦听器之外调用发射(查看流程构建器下方)
您似乎正在尝试从 Android 位置服务获取最后一个位置。这是TaskGoogle Play 服务中的许多返回调用之一。Kotlin 已经有一个模块,kotlinx-coroutines-play-services,它提供了一个函数
suspend fun <T> Task<T>.await(): T?
Run Code Online (Sandbox Code Playgroud)
在您的项目中,您可以简单地编写以下内容:
suspend fun getMyLocation(): Location? =
LocationServices.getFusedLocationProvider(context)
.lastLocation
.await()
Run Code Online (Sandbox Code Playgroud)
如果要将其与其他Flow基于代码的代码集成,请添加此包装函数:
fun <T> Task<T>.asFlow() = flow { emit(await()) }
Run Code Online (Sandbox Code Playgroud)
现在你可以写
fun getLocationAsFlow(): Flow<Location?> =
LocationServices.getFusedLocationProvider(context)
.lastLocation
.asFlow()
Run Code Online (Sandbox Code Playgroud)
如果出于教育目的,您想了解如何在没有附加模块的情况下直接实现它,那么最直接的方法如下:
fun getLocationAsFlow() = flow {
val location = suspendCancellableCoroutine<Location?> { cont ->
LocationServices.getFusedLocationProvider(context)
.lastLocation
.addOnCompleteListener {
val e = exception
when {
e != null -> cont.resumeWithException(e)
isCanceled -> cont.cancel()
else -> cont.resume(result)
}
}
}
emit(location)
}
Run Code Online (Sandbox Code Playgroud)
这是将 的简化实现内联Task.await()到其使用站点的结果。
| 归档时间: |
|
| 查看次数: |
2898 次 |
| 最近记录: |