代码之家  ›  专栏  ›  技术社区  ›  Bryan

如何使用RxAndroid和Retrofit 2检索响应主体?

  •  9
  • Bryan  · 技术社区  · 9 年前

    我正在使用Retrofit 2(beta 4),我希望不再使用标准 Call 对RxAndroid的响应 Observable 回答我成功地将大部分电话从 Call<List<ExampleObject>> Observable<List<ExampleObject>> 。我的一些电话使用 Call<okhttp3.ResponseBody> ,这很好,但当我换掉 呼叫 ,我遇到一个错误:

    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
    

    我使用 ResponseBody 因为在这些情况下,我需要解析HTML,而且据我所知,HTML解析器没有Retrofit转换器。我知道我可能可以自己创建一个,但我宁愿不解析少量的HTML。

    我的问题是为什么Retrofit 2 RxJava适配器不支持 响应主体 改装2本身是什么时候?有没有其他方法可以从 可观察的 ?


    我的服务:

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

    相关改装代码:

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

    响应尝试:

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

    新堆栈跟踪:

    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 回复  |  直到 9 年前
        1
  •  19
  •   Tudor Luca    9 年前

    试试这样的方法:

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

    编辑 :不要忘记您必须为RxJava指定适配器:

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