Retrofit2.0 using with rxjava will do costly reflection in mian thread even using subscribeOn()


元气小坏坏 提交于 2019-12-12 18:27:50

问题


Retrofit interface that return observable

interface WeatherApi {
  companion object {
      val HOST = "https://api.heweather.com/x3/"
      val KEY = "41054a8f1d1a4ac992b1683e47a50146"
  }

  @GET("weather")
  fun getWeather(@Query("city") city: String, @Query("key") key: String) : Observable<Weather>
}

RestApi:

class RestApi {
var weatherApi: WeatherApi
init {
    val logInterceptor = HttpLoggingInterceptor()
    logInterceptor.level = HttpLoggingInterceptor.Level.BODY
    val okClient = OkHttpClient.Builder()
            .addInterceptor(logInterceptor)
            .retryOnConnectionFailure(true)
            .connectTimeout(15, TimeUnit.SECONDS)
            .build()
    val retrofit = Retrofit.Builder()
            .baseUrl(WeatherApi.HOST)
            .addConverterFactory(JacksonConverterFactory.create(ObjectMapper().registerModule(KotlinModule())))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(okClient)
            .build()

    weatherApi = retrofit.create(WeatherApi::class.java)
}

fun getWeatherData(city: String, key: String): Observable<Weather> {
    return weatherApi.getWeather(city, key)  
}

Fire code:

restApi.getWeatherData("Qingdao", WeatherApi.KEY)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { t -> helloText?.text = t.data.first().basic.city }

When first calling firecode, it will cost 3 seconds to do reflection things in main thread, I'm confused,cause I have used subscribeOn(Schedulers.io()).

I do not have enough reputation to post an image, see trace pic in links below http://ww2.sinaimg.cn/large/83f914a2jw1f6sn10bt2gj218g0p0qio.jpg

When I change Retrofit interface to return "Call" and wrap response with Observable in RestApi, things will be correct.

Retrofit interface that return Call

interface WeatherApi {
companion object {
    val HOST = "https://api.heweather.com/x3/"
    val KEY = "41054a8f1d1a4ac992b1683e47a50146"
}

@GET("weather")
fun getWeather(@Query("city") city: String, @Query("key") key: String) : Call<Weather>

}

Create Observable myself in RestApi:

fun getWeatherData(city: String, key: String): Observable<Weather> {
    return Observable.fromCallable { weatherApi.getWeather("qingdao",WeatherApi.KEY).execute().body() }
}

Then call fire code, all costly things will be done in Schedulers.io() thread.

I do not have enough reputation to post an image, see trace pic in links below http://ww2.sinaimg.cn/large/83f914a2jw1f6smyi73xnj218g0p0dpk.jpg

My question is:

Is this buggy?

Why directly return Observable will cause this bug?

Or What have I do wrong with Retrofit?

来源:https://stackoverflow.com/questions/38944198/retrofit2-0-using-with-rxjava-will-do-costly-reflection-in-mian-thread-even-usin

标签

工具导航Map