RxJava 实战操作

RxJava实际运用

RxJava+Retrofit网络请求

api.getBanner()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new SingleObserver<BannerBean>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
            textView.setText("loading...");
            disposables.add(d);
        }

        @Override
        public void onSuccess(@NonNull BannerBean bannerBean) {
            textView.setText(bannerBean.toString());
        }

        @Override
        public void onError(@NonNull Throwable e) {
            textView.setText(e.getMessage());
        }
    });

串行执行

StringBuffer buffer = new StringBuffer();
api.getBanner()
    .flatMap(new Function<BannerBean, SingleSource<ArticleBean>>() {
        @Override
        public SingleSource<ArticleBean> apply(BannerBean bannerBean) throws Throwable {
            buffer.append(bannerBean).append("\n\n");
            return api.getArticleList(1);
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new SingleObserver<ArticleBean>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
            textView.setText("loading...");
        }

        @Override
        public void onSuccess(@NonNull ArticleBean articleBean) {
            buffer.append(articleBean);
            textView.setText(buffer.toString());
        }

        @Override
        public void onError(@NonNull Throwable e) {
            textView.setText(e.getMessage());
        }
    });

并行执行

api.getBanner().zipWith(
    api.getArticleList(1),
    new BiFunction<BannerBean, ArticleBean, String>() {
        @Override
        public String apply(BannerBean bannerBean, ArticleBean articleBean) throws Throwable {
            StringBuffer buffer = new StringBuffer();
            buffer.append(bannerBean).append("\n\n").append(articleBean);
            return buffer.toString();
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new SingleObserver<String>() {
        @Override
        public void onSubscribe(@NonNull Disposable d) {
            disposables.add(d);
            textView.setText("loading...");
        }

        @Override
        public void onSuccess(@NonNull String o) {
            textView.setText(o);
        }

        @Override
        public void onError(@NonNull Throwable e) {
            textView.setText(e.getMessage());
        }
    });

轮询

定义实体类

public class Translation {
    public int status;
    public Content content;

    public static class Content {
        public String form;
        public String to;
        public String vendor;
        public String out;
        public int errNo;
    }

    public String show() {
        return content.out;
    }
}

定义网络请求类

public interface ApiService {
    @GET("ajax.php?a=fy&f=auto&t=auto&w=goodmorning")
    Observable<Translation> getCall();
}

...
    
public class HttpService {
    private static final String BASE_URL = "http://fy.iciba.com/";
    private ApiService apiService;

    private static class Wrapper {
        static HttpService httpService = new HttpService();
    }

    private HttpService() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        apiService = retrofit.create(ApiService.class);
    }

    public static HttpService getInstance() {
        return Wrapper.httpService;
    }

    public Observable<Translation> getCall() {
        return apiService.getCall();
    }
}   

轮询操作:

/*
参数1:第一次延迟时间
参数2:间隔时间
参数3:时间单位
 */
Observable.interval(2, 1, TimeUnit.SECONDS)
        /*
        在next之前调用
         */
        .doOnNext(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Log.e(TAG, "第" + aLong + "次轮询");
                Observable<Translation> call = HttpService.getInstance().getCall()
                call.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<Translation>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                            }
                            @Override
                            public void onNext(Translation result) {
                                Log.e(TAG, result.show());
                            }
                            @Override
                            public void onError(Throwable e) {
                                Log.e(TAG, "请求失败");
                            }
                            @Override
                            public void onComplete() {
                            }
                        });
            }
        })
        .subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            public void onNext(Long aLong) {
            }
            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "对Error事件作出响应");
            }
            @Override
            public void onComplete() {
                Log.e(TAG, "对Complete事件作出响应");
            }
        });

输出信息:

在这里插入图片描述

有条件轮询

.repeat()和[.retry()之间区别:在于什么样的终止事件会触发重订阅。

当**.repeat()接收到.onCompleted()**事件后触发重订阅。

当**.retry()接收到.onError()**事件后触发重订阅。

Observable<Translation> call = HttpService.getInstance().getCall();
call.repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
    @Override
    public ObservableSource<?> apply(Observable<Object> objectObservable) throws Exception {
        return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Object o) throws Exception {
                if (i > 3) {
                    return Observable.error(new Throwable("轮询结束"));
                }
                return Observable.just(1).delay(2000, TimeUnit.MILLISECONDS);
            }
        });
    }
})
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Observer<Translation>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(Translation result) {
            // e.接收服务器返回的数据
            Log.e(TAG, result.show());
            i++;
        }

        @Override
        public void onError(Throwable e) {
            Log.d(TAG, e.toString());
        }

        @Override
        public void onComplete() {
        }
    });

网络请求出错重连

Observable<Translation> call = HttpService.getInstance().getCall();
call.retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
    @Override
    public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Throwable throwable) throws Exception {
                Log.e(TAG, "发生异常: " + throwable.toString());
                if (throwable instanceof IOException) {
                    Log.e(TAG, "属于io异常");
                    if (currentRetryCount < maxConnectCount) {
                        currentRetryCount++;
                        Log.e(TAG, "重试次数:" + currentRetryCount);
                        waitRetryTime = 1000 + currentRetryCount * 1000;
                        Log.e(TAG, "等待时间:" + waitRetryTime);
                        return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS);
                    } else {
                        return Observable.error(new Throwable("充实次数超过最大次数" + currentRetryCount));
                    }
                } else {
                    return Observable.error(new Throwable(("发生了非网络异常")));
                }
            }
        });
    }
}).subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Observer<Translation>() {
        @Override
        public void onSubscribe(Disposable d) {
        }

        @Override
        public void onNext(Translation result) {
            Log.e(TAG, result.show());
        }

        @Override
        public void onError(Throwable e) {
            // 获取停止重试的信息
            Log.e(TAG, e.toString());
        }

        @Override
        public void onComplete() {

        }
    });

输出信息:

发生异常: java.net.UnknownHostException: Unable to resolve host "fy.iciba.com": No address associated with hostname
属于io异常
重试次数:1
等待时间:2000
发生异常: java.net.UnknownHostException: Unable to resolve host "fy.iciba.com": No address associated with hostname
属于io异常
重试次数:2
等待时间:3000
早安

从内存缓存/磁盘读取数据

final String memoryCache = null;
final String diskCache = "磁盘保存的数据";

/**
* 检查内存缓存
*/
Observable<String> memory = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        //判断内存缓存是否有数据
        if (memoryCache != null) {
            //有数据发送
            emitter.onNext(memoryCache);
        } else {
            //没数据结束事件
            emitter.onComplete();
        }
    }
});

/**
* 检查磁盘缓存
*/
Observable<String> disk = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        //判断磁盘是否有数据
        if (diskCache != null) {
            //有数据
            emitter.onNext(diskCache);
        } else {
            //无数据
            emitter.onComplete();
        }
    }
});

/**
* 从网络获取数据
*/
Observable<String> network = Observable.just("从网络获取数据");

Observable.concat(memory, disk, network)
    .firstElement() // 只发送第一个有效数据
    .subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e(TAG, "accept: " + s);
        }
    });

输出信息:

accept: 磁盘保存的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值