使用 kotlin 协程作用域的最佳方式 - android
Best way to use kotlin coroutine scope - android
我是 android 和 kotlin 协程的新手。我一直在使用带有协程的 okhttp API lib。下面是代码:
应用扩展Class:
class App: Application() {
companion object {
val SCOPE = CoroutineScope(Dispatchers.Main)
}
}
在 MainActivity 中 class:
App.SCOPE.launch {
val results = Api.get(url)
UpdateUI(results)
}
Api class:
suspend fun get(url: String): String = withContext(Dispatchers.IO) {
try {
val data = httpClient.newCall(request).execute()
return@withContext data.body!!.string()
} catch (e: Exception) {
throw java.lang.Exception(e.message)
}
}
这工作正常,但这是最好的方法吗?
请阅读 medium article 关于不应取消的操作。
否则,对于即使 activity 和片段生命周期被破坏也需要执行的非常重要的操作似乎是正确的。
但是在您的情况下,您只是在更新 UI,因此当您进行网络调用的 activity 被破坏时,仍然继续网络调用或等待其响应是否有意义?因此,您可能应该使用生命周期协程范围,因为它们的范围仅限于组件的生命周期。请看这个 android documentation
此外,您可以使用改造来减少样板,因为改造也支持协程,您可以在改造 Api 接口中使用暂停修饰符,并且内部改造会自动将调度程序更改为 IO(使用暂停修饰符时),因此您无需手动操作。
所以您的最终代码将如下所示:
在 MainActivity 中 class:
lifecycleScope.launch {
val results = Api.get(url)
UpdateUI(results)
}
Api class:
suspend fun get(url: String): String = retrofitClient.get(url)
我是 android 和 kotlin 协程的新手。我一直在使用带有协程的 okhttp API lib。下面是代码:
应用扩展Class:
class App: Application() {
companion object {
val SCOPE = CoroutineScope(Dispatchers.Main)
}
}
在 MainActivity 中 class:
App.SCOPE.launch {
val results = Api.get(url)
UpdateUI(results)
}
Api class:
suspend fun get(url: String): String = withContext(Dispatchers.IO) {
try {
val data = httpClient.newCall(request).execute()
return@withContext data.body!!.string()
} catch (e: Exception) {
throw java.lang.Exception(e.message)
}
}
这工作正常,但这是最好的方法吗?
请阅读 medium article 关于不应取消的操作。 否则,对于即使 activity 和片段生命周期被破坏也需要执行的非常重要的操作似乎是正确的。 但是在您的情况下,您只是在更新 UI,因此当您进行网络调用的 activity 被破坏时,仍然继续网络调用或等待其响应是否有意义?因此,您可能应该使用生命周期协程范围,因为它们的范围仅限于组件的生命周期。请看这个 android documentation 此外,您可以使用改造来减少样板,因为改造也支持协程,您可以在改造 Api 接口中使用暂停修饰符,并且内部改造会自动将调度程序更改为 IO(使用暂停修饰符时),因此您无需手动操作。 所以您的最终代码将如下所示:
在 MainActivity 中 class:
lifecycleScope.launch {
val results = Api.get(url)
UpdateUI(results)
}
Api class:
suspend fun get(url: String): String = retrofitClient.get(url)