【发布时间】:2019-03-21 07:33:20
【问题描述】:
使用单块 UI 线程改进第一个请求。下面是相关代码,还有更多文字:
改造提供者
object RetrofitProvider {
private val TAG: String = RetrofitProvider::class.java.simpleName
val retrofit: Retrofit by lazy {
val httpClient = OkHttpClient.Builder()
.addInterceptor {
val request = it.request()
if (BuildConfig.DEBUG) {
Log.d(TAG, "${request.method()}: ${request.url()}")
}
it.proceed(request)
}
.build()
Retrofit.Builder()
.client(httpClient)
.baseUrl("http://192.168.0.10:3000")
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(JacksonConverterFactory.create(jacksonObjectMapper()))
.build()
}
}
产品接口
interface ProductApi {
@GET("/products")
fun getProducts(): Single<List<Product>>
}
主视图模型
fun fetchProducts() {
productData.value = Resource.Loading()
productApi.getProducts() // <- This call is a problem (even when I comment out all code below)
.subscribeOn(Schedulers.io())
.subscribe(
{
productData.postValue(Resource.Success(it))
},
{
productData.postValue(Resource.Fail(it.message))
})
.addTo(disposableContainer)
}
主片段
...
button.setOnClickListener {
Toast.makeText(requireContext(), "click", Toast.LENGTH_SHORT).show()
mainViewModel.fetchProducts()
}
...
应用流程很简单,点击 MainFragment 上的按钮会调用 MainViewModel 的 fetchProducts(),它使用改造来获取一些东西。
productApi.getProducts() 发生在 UI 线程上并显着阻塞它(~半秒),即使 Toast 被延迟,即使它应该在按钮单击时立即显示,在 之前getProducts() 调用。
productApi.getProducts() 本身,没有 subscribe 不会发送网络请求(我在服务器端检查过),它只是准备 Single。
重要提示,后续点击按钮不会发生延迟。只是第一次,我猜创建 Single 是昂贵的操作。
所以我的问题是,为什么 UI 线程在第一次请求时被阻止,以及如何修复它而不是丑陋/黑客攻击。
Observable 的作用也一样,但 Completable 工作得更快,但我需要数据,所以不能使用 Completable。
【问题讨论】:
-
您是否尝试在
subscribeOn(...)方法之后添加.observerOn(AndroidSchedulers.main())? -
是的,没用。
-
你能在 Android Studio 中使用 CPU 分析器来看看什么方法需要这么长时间吗?
标签: android kotlin retrofit rx-java2