J'utilise Retrofit 2 (beta 4), et je cherchais à passer de l'utilisation de la réponse standard Call
à la réponse RxAndroid Observable
. J'ai réussi à passer la plupart de mes appels avec un simple échange de Call<List<ExampleObject>>
à Observable<List<ExampleObject>>
. Certains de mes appels utilisent Call<okhttp3.ResponseBody>
, qui fonctionne très bien, mais quand je troqué Call
, je rencontré une erreur:Comment extraire le corps de réponse avec RxAndroid et 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 raison pour laquelle je me sers du ResponseBody
au lieu d'un autre objet, comme d'habitude, parce que dans Dans ces cas, j'ai besoin d'analyser HTML, et pour autant que je sache, il n'y a pas de convertisseur Retrofit pour un analyseur HTML. Je sais que je pourrais probablement en créer un seul, mais je préférerais ne pas utiliser la petite quantité de HTML que j'ai à analyser.
Ma question est pourquoi l'adaptateur Retrofit 2 RxJava ne prend-il pas en charge ResponseBody
lorsque Retrofit 2 lui-même le fait? Y a-t-il un autre moyen d'obtenir la chaîne de réponse d'un Observable
?
Mon service:
public interface AuthenticationService() {
@GET("cas/login")
Observable<Response<ResponseBody>> login();
}
pertinentes Code Retrofit:
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);
}
Réponse tentative:
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");
}
}
Nouvelle trace de la pile:
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
S'il vous plaît afficher le code réel. –
@TudorLuca Mis à jour avec le code – Bryan
@TudorLuca Je suis désolé de perdre votre temps. J'ai découvert que j'utilisais en fait un objet Retrofit (que j'aurais dû supprimer) qui n'avait pas de RxJavaCallAdapterFactory. Je déchire le code actuel, et c'est un peu le bordel. Merci pour votre aide de toute façon. – Bryan