How to get response body using RxAndroid and retrofit 2?

I am using Retrofit 2 (beta 4) and I was looking for a switch from using a standard Call response to an RxAndroid Observable answer. I managed to switch most of my calls with a simple swap from Call<List<ExampleObject>> to Observable<List<ExampleObject>> . Some of my calls use Call<okhttp3.ResponseBody> , which works fine, but when I changed Call , I got an error:

 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 

The reason I use ResponseBody instead of the usual object, as usual, is that in these cases I need to parse the HTML, and as far as I know, there is no Retrofit converter for the HTML parser. I know that maybe I can create it myself, but I would prefer not for a little HTML, which I should parse.

My question is: why doesn't the Retrofit 2 RxJava adapter support ResponseBody when doing Retrofit 2? Is there any other way to get response string from Observable ?


My service:

 public interface AuthenticationService() { @GET("cas/login") Observable<Response<ResponseBody>> login(); } 

Relevant revision code:

 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); } 

Answer:

 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"); } } 

New stack trace:

 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 
+7
android rx-java rx-android retrofit2
source share
1 answer

Try something like this:

 import okhttp3.ResponseBody; import retrofit2.Response; @GET("/whatever") Observable<Response<ResponseBody>> getWhatever(); 

Change Do not forget that you must specify an adapter for RxJava:

  new Retrofit.Builder() ... .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build() .create(Api.class); 
+16
source share

All Articles