RxJava/Retrofit - 如何强制用户使用特定的订阅者子类?

Posted

技术标签:

【中文标题】RxJava/Retrofit - 如何强制用户使用特定的订阅者子类?【英文标题】:RxJava/Retrofit - How can I force users to use a specific subclass of Subscriber? 【发布时间】:2016-07-28 23:36:20 【问题描述】:

在使用rx.Observable 之前,我使用了一个带有改造的自定义回调,因此我可以添加一些特定的逻辑来处理响应/错误,而不必在每个请求的回调中作为样板代码执行此操作。

我强制用户使用自定义回调,方法是将其放入方法签名中,如下所示:

@GET("/user_endpoint/")
void getUser(CustomCallback<User> callback);

@GET("/profile_endpoint/")
void getProfile(CustomCallback<Profile> callback);

但现在我要返回 Observable:

@GET("/user_endpoint/")
Observable<User> getUser();

@GET("/profile_endpoint/")
Observable<Profile> getProfile();

我想不出一种方法来确保自定义回调始终代理错误/响应。

另外,使用retrofit2.0,如何强制用户使用自定义回调和返回的Call 对象?

CustomCallback 供参考:

public abstract class CustomCallback<T> implements Callback<T> 

  @Override public final void success(T t, Response response) 
    // do some logic
    onSuccess(t);
  

  @Override public final void failure(RetrofitError error) 
    // do something with the error here such as show a Toast
    Toast.makeText(Application.getInstance(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
    onFailure(error);
  

  public abstract void onSuccess(T response);

  public abstract void onFailure(Throwable error);

【问题讨论】:

问题是为什么你需要返回一个 observable,而显然你不能使用任何 observable?为什么不让 CustomCallback 扩展 Observable 然后将其作为类型返回?当你说你想确保它代理响应时,你想在哪里代理观察者? 返回的类型必须是 rx.Observable,而不是子类 github.com/square/retrofit/blob/parent-1.4.0/retrofit/src/main/… 【参考方案1】:

停下来。你想错了。

请考虑一下:您有正常的 Retrofit 界面:

interface Foo 
   @GET("/user_endpoint/")
   Observable<User> getUser();

然后你就有了你的装饰器类:

public class FooDecorator implements Foo 
    private Foo delegate = ...; // inject or create the Retrofit instance.

    @Override
    public Observable<User> getUser() 
       return delegate.getUser().doOnNext(...).doOnError(...);
    

然后你在代码中的任何地方只使用第二个类(最好让 DI 系统使用它),然后你就设置好了。

如果您喜欢冒险,您甚至可以调整 RxJavaCallAdapterFactory 以便它修改返回的 observables 而无需自定义类。

【讨论】:

我知道创建一个装饰器类是可行的,但它需要你用相同的逻辑实现每个方法。我一直在寻找更清洁的解决方案。 RxJavaCallAdapterFactory github.com/square/retrofit/blob/master/retrofit-adapters/rxjava/… 是最后一课,所以我必须使用我自己的改造分支,这不是我正在寻找的解决方案 如果你愿意,你可以使用java.lang.reflext.Proxy 来进行包装,那么你就不需要显式的类了。

以上是关于RxJava/Retrofit - 如何强制用户使用特定的订阅者子类?的主要内容,如果未能解决你的问题,请参考以下文章

Android实战——RxJava2+Retrofit+RxBinding解锁各种新姿势

如何使用Retrofit2,RxJava2,Gson TypeAdapterFActory正确映射Gson?

如何使用 rxjava/retrofit 正确等待/观察来自服务器的传入数据

RxJava+Retrofit+OkHttp深入浅出-mvp(使用篇)

RxJava + Retrofit 的实际应用场景

RxJava + Retrofit完成网络请求