Android:使用网络拦截器中的数据在不破坏体系结构的情况下完成与UI相关的工作
有时,API可以在完成网络调用之前决定执行ui作业(例如,显示webview对话框)。这些标志位于响应头中,值通常是数据,如该webview的url 这是拦截器Android:使用网络拦截器中的数据在不破坏体系结构的情况下完成与UI相关的工作,android,kotlin,mvvm,kotlin-coroutines,Android,Kotlin,Mvvm,Kotlin Coroutines,有时,API可以在完成网络调用之前决定执行ui作业(例如,显示webview对话框)。这些标志位于响应头中,值通常是数据,如该webview的url 这是拦截器 override fun intercept(chain: Interceptor.Chain): Response { val response = chain.proceed(request) return when (response.code()) { 200 -&
override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(request)
return when (response.code()) {
200 -> {
response.headers().forEach { /* do something in ui layer if needed */}
response;
}
}
}
避免使用EventBus,因此我会将元数据对象添加到响应中,然后将其传递到存储库并在viewmodel中对其进行解析,并为
活动
和片段
生成事件,但我们不知道何时触发此拦截,因此必须为每个api调用检查所有viewmodels中的所有类型的事件。解决方案是在api结果中添加一个InterceptionMetaData
data class InterceptionMetaData(
val key: String,
val data: String
)
将此数据类添加到响应(通常为成功类型,或者我们可以添加另一个截获的响应类型)
在我们的拦截器中,我们检查响应头(我在这里使用了所有头进行演示)
通常我们有基本视图模型,因此我们可以让我们的BaseViewModel
构建一个事件,并将其传递给我们的BaseFragment/BaseActivity
,以处理实际的ui作业(例如启动一个对话框)。该功能用于我放置Log.d
的地方
when (this) {
is Success -> success?.invoke(this.data, metaData)
is Error -> error?.invoke(this.error)
is Loading -> loading?.invoke()
is Intercepted -> onIntercepted?.invoke(this.data, interceptionMetaDataList)
}
val interceptionMetaDataList: List<InterceptionMetaData> = response.headers().run {
names().map { key ->
get(key)?.let { InterceptionMetaData(key, it) }
}
}.filterNotNull()
repository.getNewsList().collectResult(
onIntercepted = { data, interceptionList ->
Log.d(NewsViewModel::class.java.simpleName, "getNewsList: $interceptionList")
},
success = { data ->
hideProgress()
handleData(data)
},
error = { error ->
hideProgress()
showNoData(error)
},
loading = {
showProgress()
})