一、定义Rxjava
RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库,符合观察者设计模式
二、特点
逻辑简洁、使用优雅、使用简单
三、基本用法
//1.创建被观察者
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.d(TAG,"发送数据");
}
});
//2.创建观察者
Observer<Integer> observer=new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG,"接收到数据===:"+integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
//3.订阅关系
observable.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
下面主要总结是我用Retrofit和Rxjava2写的网络请求,以及网络出错重连的demo。
demo界面:
1.添加依赖
implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
//Gson converter
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
//RxJava2 Adapter
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
2.接口类
public interface API {
@Headers({"Content-Type:application/json;charset=utf-8", "Accept:application/json;"})
@FormUrlEncoded
@POST("weather/index")
Observable<ErrorResponse> requestWeather(@FieldMap Map<String,String> route);
@GET("v2/movie/top250?start=0")
Observable<Video> reqVideoList();
@GET("v2/movie/top250")
Observable<Video> reqVideoList2(@Query("start") String start);
}
3.Retrofit管理类
public class RetrofitManager {
public static Retrofit getInstance(String baseUrl){
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(5, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
return new Retrofit.Builder().baseUrl(baseUrl)// 设置 网络请求 Url
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())//设置使用Gson解析
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())// 支持RxJava
.build();
}
}
4.GET请求例子
请求豆瓣电影排行250,完整API:
https://api.douban.com/v2/movie/top10?start=0
数据类型:
代码:
String videoUrl = "https://api.douban.com/";
RetrofitManager.getInstance(videoUrl).create(API.class)
.reqVideoList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Video>() {
@Override
public void accept(Video video) throws Exception {
tv_result.setText(video.getSubjects().get(0).getTitle());
Log.d(TAG,"响应数据:"+video.getSubjects().get(0).getTitle());
}
});
5.POST请求
请求天气API:
http://v.juhe.cn/weather/index
因为key过期不能请求到具体的,这里返回它错误的信息,能返回即请求成功
String mWeather="http://v.juhe.cn/";
final HashMap<String,String> map=new HashMap<>();
map.put("key","6a6fcd002b4db0016cd8b01528d0ceef");
map.put("cityname","上海");
RetrofitManager.getInstance(mWeather)
.create(API.class)
.requestWeather(map)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ErrorResponse>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ErrorResponse errorResponse) {
Log.d(TAG,"请求成功:"+errorResponse.toString());
tv_result.setText(errorResponse.toString());
}
@Override
public void onError(Throwable e) {
Log.e(TAG,"onError:"+e.getMessage());
}
@Override
public void onComplete() {
}
});
6.网络出错重连(操作符RetryWhen)
retryWhen是Rxjava2中异常捕获操作符,代码实例:
// 可重试次数
int maxCount = 10;
// 当前已重试次数
int currCount = 0;
public void reConnection(View v){
String videoUrl = "https://api.douban.com/";
RetrofitManager.getInstance(videoUrl).create(API.class)
.reqVideoList()
.retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {//retryWhen:当出现错误时捕获,被观察者重新发送事件
@Override
public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {//flatMap:将被观察发送的事件拆分,单独转换然后合并为一个新的事件序列
@Override
public ObservableSource<?> apply(Throwable throwable) throws Exception {
if(throwable instanceof IOException){
if (currCount < maxCount){
currCount++;
Log.d(TAG, "重试次数 = " + currCount);
return Observable.just(1).delay(3000, TimeUnit.MILLISECONDS);//发送一个为1的事件通知被观察者重新请求
}else{
return Observable.error(new Throwable("重连次数已达上限"));//出发onError事件结束重连
}
}else{
}
return null;
}
});
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Video>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Video video) {
Log.d(TAG,"请求结果:"+video.getSubjects().get(0).getTitle());
}
@Override
public void onError(Throwable e) {
Log.e(TAG,"onError:"+e.getMessage());
}
@Override
public void onComplete() {
}
});
}
其中某些实体类没有具体给出,可以看看demo源码,从上面可以看出来在整个网络请求的过程中,链式调用方法,代码简洁,没有过多的嵌套,线程切换自如,更多关于Rxjava2的操作符可以解决实际开发中的各种问题的需要大家多多学习,这里只是给出了一个小小的展示