android - 用于改造响应代码处理的自定义 rx Func1

标签 android rx-java retrofit2 rx-android

我是rxjava新手,所以请不要严格......

我有请求虱子下一个:

Observable<Login>login(String l, String p){
        return api.loginUser(l,p)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Func1<Response<Login>, Observable<? extends Login>>() {
                    @Override
                    public Observable<? extends Login> call(Response<Login> r) {
                        switch (r.code()){
                            case 200:
                                requestOk(r);
                                break;
                            case 202:
                                //need to Repeat
                                login.timeout(2000,TimeUnit.Milliseconds);
                                break;
                            default:
                                //
                        }
                    }
                });
    }

Observable<Login> requestOk(final Response<Login> r){
            return Observable.create(new Observable.OnSubscribe<Login>(){
                @Override
                public void call(Subscriber<? super Login> subscriber) {
                    if (subscriber.isUnsubscribed()) return;
                    subscriber.onNext(r.body());
                    subscriber.onCompleted();
                }
            });
        }

工作正常。但是还会有很多其他请求,我需要检查请求代码以防重复。

所以我试图创建自定义 Func1 - 适用于所有请求:

private <T>Func1<? super Response<T>, ? extends Observable<? extends T>> customFunc(final Observable<T> o) {
        return new Func1<Response<T>, Observable<? extends T>>() {
            @Override
            public Observable<? extends T> call(Response<T> r) {
                switch (r.code()){
                    case 200:
                        //
                        break;
                    case 202:
                        //need to Repeat
                        return o.timeout(2000,TimeUnit.Milliseconds);
                        break;
                    default:
                        //
                }
            };
        };
    }

我一直坚持将登录可观察中的当前可观察放入 customFunc 中。

我相信一定有其他更简单且正确的方法来做到这一点。 很高兴有任何帮助!

最佳答案

您可以使用Transformer为了创建通用状态代码验证器:

class StatusCodeVerifierTransformer<T> implements Observable.Transformer<Response<T>, T> {

    @Override
    public Observable<T> call(Observable<Response<T>> responseObservable) {
        return responseObservable.flatMap(new Func1<Response<T>, Observable<T>>() {
            @Override
            public Observable<T> call(Response<T> loginResponse) {
                switch (loginResponse.code()) {
                    case 200:
                        return Observable.just(loginResponse.body());
                    case 202:
                        //need to Repeat
                        return Observable.error(new Status202Exception());
                    default:
                        return Observable.error(new Exception("unknown error"));
                }
            }
        });

    }
}

这个变压器将接受任何 ObservableResponse<T>并将其转换为 ObservableT ,根据您的策略发出错误。
然后将其与 compose() 一起使用运算符:

  Observable<Login> login(String l, String p) {
    return api.loginUser(l, p)
            .compose(new StatusCodeVerifierTransformer<>())
   }

现在你有一个Observable将发出 onError根据您的状态代码处理,使用您想要的异常。

现在,您可以像任何 Observable 一样重试错误。与 retry运算符,例如这样:

 api.loginUser(l, p)
            .compose(new StatusCodeVerifierTransformer<>())
            .retry(new Func2<Integer, Throwable, Boolean>() {
                @Override
                public Boolean call(Integer retryCount, Throwable throwable) {
                    return throwable instanceof Login202Exception && retryCount < MAX_RETRY;
                }
            })

顺便说一句,一些评论:

requestOk - 你绝对不需要创建Observable要发出一次特定值,只需使用 just()运算符,如 StatusCodeVerifierTransformer 中的例子。 (或者对于任何其他同步操作,您有很多运算符,例如 fromCallable()just()from() )
一般来说,create()不是创建 Observable 的安全方法不再了。

关于android - 用于改造响应代码处理的自定义 rx Func1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42421234/

相关文章:

android - 连接不同类型的可观察对象

Android kotlin MVVM - 你可以在 recyclerview 适配器中调用 viewmodel 吗?

android - 如何在 Retrofit 2 中上传图像文件

Android Retrofit 2.0 JSON 文档未完全消耗

java - 一个简单的误解: How can I incorporate java class on Android

android - 如何从 RecyclerView 共享图像?

java - 不显示全文的Textview

rx-java - 关于返回订阅者的 subscribeWith 方法的用法

android - 如何通过游标读取数据库中的多列并填充到列表中?

java - 如何从 Retrofit2 拦截器开始登录 Activity