Sto usando Retrofit 2 (beta 4) e stavo cercando di passare dalla risposta standard Call
alla risposta RxAndroid Observable
. Sono riuscito a passare la maggior parte delle mie chiamate con un semplice scambio da Call<List<ExampleObject>>
a Observable<List<ExampleObject>>
. Alcuni dei miei chiamate usano Call<okhttp3.ResponseBody>
, che funziona benissimo, ma quando ho scambiato fuori Call
, mi sono incontrato con un errore:Come recuperare il corpo di risposta con RxAndroid e Retrofit 2?
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
La ragione per cui sto usando la ResponseBody
invece di un altro oggetto, come al solito, è perché in In questi casi ho bisogno di analizzare HTML e, per quanto ne so, non esiste un convertitore Retrofit per un parser HTML. So che probabilmente potrei crearne uno da solo, ma preferirei non la piccola quantità di codice HTML che devo analizzare.
La mia domanda è: perché l'adattatore Retrofit 2 RxJava supporta ResponseBody
quando lo stesso Retrofit 2 lo fa? C'è un altro modo per ottenere la stringa di risposta da un Observable
?
mio servizio:
public interface AuthenticationService() {
@GET("cas/login")
Observable<Response<ResponseBody>> login();
}
codice Retrofit Rilevante:
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);
}
tentativo di risposta:
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");
}
}
Nuovo 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
si prega di inviare il codice vero e proprio. –
@TudorLuca Aggiornato con il codice – Bryan
@TudorLuca Mi dispiace per aver perso tempo. Ho scoperto che stavo usando un oggetto Retrofit (che avrei dovuto eliminare) che non aveva un RxJavaCallAdapterFactory. Sto facendo a pezzi il codice attuale, ed è un po 'un casino. Grazie per il tuo aiuto comunque. – Bryan