2017-09-27 5 views
0

APIを呼び出すためにKotlinで書かれたAndroidアプリケーションでRetrofit 2を使用しています。
私の呼び出しは次のようになります。次のようにgeocodingApiは私のクラスのコンストラクタで初期化されるRetrofits call.enqueueが最初のリクエストをブロックしています

val time = measureTimeMillis { 
    val call = geocodingApi.searchByName("Berlin") 
    call.enqueue(object : Callback<GeocodingResponse> { 
     override fun onResponse(call: Call<GeocodingResponse>?, response: Response<GeocodingResponse>?) { 
      // some code 
     } 

     override fun onFailure(call: Call<GeocodingResponse>?, t: Throwable?) { 
      // some code 
     } 

    }) 
} 
Timber.d("searching by name took $time ms") 

val loggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { Timber.d(it) }) 
loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS 

val client = OkHttpClient 
     .Builder() 
     .addInterceptor(loggingInterceptor) 
     .addInterceptor(GoogleApiKeyInterceptor()) 
     .build() 

val retrofit = Retrofit.Builder() 
     .baseUrl(BASE_URL) 
     .addConverterFactory(ScalarsConverterFactory.create()) 
     .addConverterFactory(MoshiConverterFactory.create(Moshi.Builder().add(KotlinJsonAdapterFactory()).build())) 
     .client(client) 
     .build() 

geocodingApi = retrofit.create(GeocodingApi::class.java) 

初期化が許容され、80ミリ秒を周りになります。問題は、最初の呼び出しでUIスレッドをブロックするのに1.5秒から2秒かかります。後続のすべての呼び出しは直ちに戻り、呼び出しが終了した後でそのコールバックを呼び出します。ログには、次のようになります。

searching by name took 1864 ms 
searching by name took 3 ms 
searching by name took 4 ms 
searching by name took 2 ms 

ことは可能であろう別のスレッドですべての呼び出しをラップし、期待される結果(ノーUIブロッキング)を生成するが、バックグラウンドで結果を実行する必要がありcall.enqueueを呼び出すマニュアルに従って最初の呼び出しを除いて、すべてのアプリケーションで機能します。
何か間違っていますか?私はRetrofit 2.3.0とOkHttp 3.8.1を使用しています。

ありがとうございます!

+0

私は同じ問題があります。あなたはそれを解決しましたか? – yaneq6

+0

@ yaneq6残念ながら。私はMoshiConverterFactoryによって引き起こされる問題を追跡し、動作するGsonに切り替えました。私はmoshi githubページで問題を作成しました。多分同じ問題があることをコメントできます:https://github.com/square/moshi/issues/362 – Phoca

答えて

1

追加ライブラリKotshiを使用して問題を解決し、KotlinJsonAdapterFactoryの代わりに使用します。 Kotshiは、コンパイル時に注釈を分析するためにkaptを使用して、実行時に注釈を解析するという膨大なオーバーヘッドを回避します。レトロフィットBuilder内

にのみ必要ステップは
.addConverterFactory(MoshiConverterFactory.create(Moshi.Builder().add(ApplicationJsonAdapterFactory.INSTANCE).build()))

によって
.addConverterFactory(MoshiConverterFactory.create(Moshi.Builder().add(KotlinJsonAdapterFactory()).build()))
を交換することで、シリアライズ可能なモデルとして使用されるすべてのデータクラスは@JsonSerializableで注釈を付けるべきです。

関連する問題