【发布时间】:2020-01-03 12:42:29
【问题描述】:
通过使用 LiveData 的最新版本“androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha03”,我使用 LiveData 的新构建块(LiveData +协程),它使用 Retrofit 执行同步网络调用,并相应地更新 ViewModel 中的不同标志(isLoading、isError)。我在“查询”LiveData 上使用 Transforamtions.switchMap,因此每当 UI 中的“查询”发生变化时,“搜索产品”代码就会使用 Transformations.switchMap 开始执行。一切正常,除了我想在“查询”LiveData 发生变化时取消之前的改造调用。目前我看不到任何方法可以做到这一点。任何帮助,将不胜感激。
class ProductSearchViewModel : ViewModel() {
val completableJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)
// Query Observable Field
val query: MutableLiveData<String> = MutableLiveData()
// IsLoading Observable Field
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
val products: LiveData<List<ProductModel>> = query.switchMap { q ->
liveData(context = coroutineScope.coroutineContext) {
emit(emptyList())
_isLoading.postValue(true)
val service = MyApplication.getRetrofitService()
val response = service?.searchProducts(q)
if (response != null && response.isSuccessful && response.body() != null) {
_isLoading.postValue(false)
val body = response.body()
if (body != null && body.results != null) {
emit(body.results)
}
} else {
_isLoading.postValue(false)
}
}
}
}
【问题讨论】:
-
你的改造界面是什么样的?您是否使用暂停并直接返回数据?您应该在返回类型上使用 Call 接口包装数据并保留对它的引用,以便在触发 switchMap 时取消它。
-
改造界面包含挂起功能。暂停有趣的 searchProducts(@Query("query") query: String)
-
保留对 Call 接口的引用并取消它是一种更好的方法,但是还有其他方法应该类似于取消 Coroutine Job 并且其所有暂停的功能都会自动停止吗?
-
在这种情况下 - 如果您取消范围,呼叫也应该被取消。
-
您能否指出在上面共享的示例中将此范围取消代码放置在何处?
标签: android kotlin android-livedata kotlin-coroutines kotlin-extension