2016-03-03 23 views
7

Retrofit 2 (beta 4) kullanıyorum ve RxAndroid Observable yanıtına standart Call yanıtını kullanıyorum. Aramalarımın çoğunu Call<List<ExampleObject>>'dan Observable<List<ExampleObject>>'a basit bir şekilde değiştirerek başarılı oldum. aramalarıma Birkaç inşaat büyük ama Call takas, ben bir hata ile karşılandı Call<okhttp3.ResponseBody> kullanın:RxAndroid ve Retrofit 2 ile Yanıt Gövdesini Nasıl Alınır?

03-03 15:21:44.237 27333-27333/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main 
     Process: com.example.app, PID: 27333 
     java.lang.IllegalArgumentException: Unable to create call adapter for rx.Observable<okhttp3.ResponseBody> 
      for method AuthenticationService.getLoginForm 
      at retrofit2.Utils.methodError(Utils.java:119) 
      at retrofit2.MethodHandler.createCallAdapter(MethodHandler.java:52) 
      at retrofit2.MethodHandler.create(MethodHandler.java:25) 
      at retrofit2.Retrofit.loadMethodHandler(Retrofit.java:164) 
      at retrofit2.Retrofit$1.invoke(Retrofit.java:145) 
      at java.lang.reflect.Proxy.invoke(Proxy.java:393) 
      at $Proxy6.getLoginForm(Unknown Source) 
      at com.example.app.ui.fragment.LoginFragment.login(LoginFragment.java:214) 
      at com.example.app.ui.fragment.LoginFragment.lambda$onContinue$1(LoginFragment.java:168) 
      at com.example.app.ui.fragment.LoginFragment.access$lambda$1(LoginFragment.java) 
      at com.example.app.ui.fragment.LoginFragment$$Lambda$4.onClick(Unknown Source) 
      at android.view.View.performClick(View.java:5204) 
      at android.view.View$PerformClick.run(View.java:21153) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:148) 
      at android.app.ActivityThread.main(ActivityThread.java:5417) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
     Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for rx.Observable<okhttp3.ResponseBody>. 
     Tried: 
      * retrofit2.ExecutorCallAdapterFactory 
      at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:230) 
      at retrofit2.Retrofit.callAdapter(Retrofit.java:194) 
      at retrofit2.MethodHandler.createCallAdapter(MethodHandler.java:50) 
       ... 18 more 

nedeni yerine her zamanki gibi başka bir nesnenin ResponseBody kullanıyorum, olduğu çünkü bu durumlarda HTML'yi ayrıştırmam gerekiyor ve bildiğim kadarıyla, bir HTML ayrıştırıcısı için herhangi bir dönüştürme dönüştürücüsü yok. Biliyorum muhtemelen kendi başıma bir tane oluşturabilirim, ama ayrıştırmak zorunda olduğum küçük miktardaki HTML için tercih etmem.

Sorum şu; neden Retrofitler 2 RxJava Adaptör destek ResponseBody Güçlendirme 2 kendisinin yapar? Yanıt dizesini Observable'dan başka bir şekilde alabilir miyim?


Benim Hizmeti:

public interface AuthenticationService() { 

    @GET("cas/login") 
    Observable<Response<ResponseBody>> login(); 
} 

İlgili Uyarlama kodu:

public static Retrofit getRetrofit() { 
    if(mRetrofit == null) { 
     return new Retrofit.Builder() 
       .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
       .addConverterFactory(GsonConverterFactory.create(getGson())) 
       .client(getOkHttpClient()) 
       .build(); 
    } return mRetrofit; 
} 

public static AuthenticationService getAuthenticationService() { 
    return getRetrofit().create(AuthenticationService.class); 
} 

Tepki girişimi:

private void login() { 
    RestClient.getAuthenticationService().login() 
      .observeOn(ASchedulers.newThread()) 
      .subscribeOn(AndroidSchedulers.mainThread()) 
      .doOnNext(this::onLoginResponse); 
} 

private void onLoginResponse(Response<ResponseBody>> response) { 
    try { 
     parseResponse(response.body().string()); 
    } catch (IOException) { 
     Timber.w(throwable, "Failed to login"); 
    } 
} 

Yeni yığın izleme:

Böyle
03-03 16:14:57.848 26866-26866/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main 
     Process: com.example.app, PID: 26866 
     java.lang.IllegalArgumentException: Unable to create call adapter for rx.Observable<retrofit2.Response<okhttp3.ResponseBody>> 
      for method AuthenticationService.getLoginForm 
      at retrofit2.Utils.methodError(Utils.java:119) 
      at retrofit2.MethodHandler.createCallAdapter(MethodHandler.java:52) 
      at retrofit2.MethodHandler.create(MethodHandler.java:25) 
      at retrofit2.Retrofit.loadMethodHandler(Retrofit.java:164) 
      at retrofit2.Retrofit$1.invoke(Retrofit.java:145) 
      at java.lang.reflect.Proxy.invoke(Proxy.java:393) 
      at $Proxy3.getLoginForm(Unknown Source) 
      at com.example.app.ui.fragment.LoginFragment.login(LoginFragment.java:206) 
      at com.example.app.ui.fragment.LoginFragment.lambda$onContinue$1(LoginFragment.java:160) 
      at com.example.app.ui.fragment.LoginFragment.access$lambda$1(LoginFragment.java) 
      at com.example.app.ui.fragment.LoginFragment$$Lambda$4.onClick(Unknown Source) 
      at android.view.View.performClick(View.java:5204) 
      at android.view.View$PerformClick.run(View.java:21153) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:148) 
      at android.app.ActivityThread.main(ActivityThread.java:5417) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
     Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for rx.Observable<retrofit2.Response<okhttp3.ResponseBody>>. 
     Tried: 
      * retrofit2.ExecutorCallAdapterFactory 
      at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:230) 
      at retrofit2.Retrofit.callAdapter(Retrofit.java:194) 
      at retrofit2.MethodHandler.createCallAdapter(MethodHandler.java:50) 
       ... 18 more 
+1

gerçek kod sonrası edin: RxJava için adaptör belirtmek zorunda unutmayın. –

+0

@TudorLuca Kod ile güncellendi – Bryan

+0

@TudorLuca Zamanınızı boşa harcadığım için üzgünüm. Aslında bir RxJavaCallAdapterFactory olmayan bir Retrofit nesnesi (silmemeliyim) kullandığımı öğrendim. Şu anki kodu parçalara ayırıyorum ve biraz dağınık. Yine de yardım ettiğin için teşekkür ederim. – Bryan

cevap

16

deneyin şey:

import okhttp3.ResponseBody; 
import retrofit2.Response; 

@GET("/whatever") 
Observable<Response<ResponseBody>> getWhatever(); 

Düzenleme:

new Retrofit.Builder() 
      ... 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build() 
      .create(Api.class); 
+0

Bunu denedi, aynı sonuç:/Ben de bir düz 'okhttp3.Respone denedim, bu da işe yaramıyor. – Bryan

+0

Evet, diğer "Gözlemlenebilir " yanıtları beklendiği gibi çalıştığı için, 'RxJavaCallAdapterFactory' doğru şekilde ayarlanmış. – Bryan

+2

Bu, okhttp3.Respone ile çalışmayacak, Retrofit'in Yanıtına ihtiyacınız var. –

İlgili konular