系列文章
RxJava系列之简介和观察者设计模式
RxJava系列之上游与下游
RxJava系列之常用创建型操作符
RxJava系列之常用变换操作符
RxJava系列之常用过滤操作符
RxJava系列之常用条件操作符
RxJava系列之常用合并操作符
RxJava系列之常用异常操作符
RxJava系列之线程切换实战
RxJava系列之背压模式
RxJava系列之配合Retrofit
RxJava系列之泛型高级
RxJava系列之手写create操作符
RxJava系列之手写create操作符增加泛型限定
RxJava系列之手写just操作符
RxJava系列之手写map操作符
RxJava系列之手写切换线程
Retrofit
retrofit是网络封装库,内部网络请求交由OkHttp来做的。本文中使用RxJava+Retrofit实现下面这样的需求:
需求:
1.请求服务器注册操作
2.注册完成之后,更新注册UI
3.马上去登录服务器操作
4.登录完成之后,更新登录的UI
定义网络请求接口
public interface IRequestNetwork {
// 请求注册 功能 todo 耗时操作 ---> OkHttp
public Observable<RegisterResponse> registerAction(@Body RegisterRequest registerRequest);
// 请求登录 功能 todo 耗时操作 ---> OKHttp
public Observable<LoginResponse> loginAction(@Body LoginRequest loginRequest);
}
创建实体类
RegisterRequest,RegisterResponse,LoginRequest,LoginResponse。没有具体的实现,只是伪代码。
实现需求
public class TestActivity extends AppCompatActivity {
private final String TAG = TestActivity.class.getSimpleName();
private TextView tv_register_ui;
private TextView tv_login_ui;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
tv_register_ui = findViewById(R.id.tv_login_ui);
tv_login_ui = findViewById(R.id.tv_login_ui);
}
// 方法1
public void request(View view) {
// 分开写
/**
* 1.请求服务器注册操作
* 2.注册完成之后,更新注册UI
*/
// IRequestNetwork iRequestNetwork = MyRetrofit.createRetrofit().create(IRequestNetwork.class);
// 1.请求服务器注册操作
MyRetrofit.createRetrofit().create(IRequestNetwork.class) // IRequestNetwork
// IRequestNetwork.registerAction
.registerAction(new RegisterRequest()) // Observable<RegisterResponse> 上游 被观察者 耗时操作
.subscribeOn(Schedulers.io()) // todo 给上游分配异步线程
.observeOn(AndroidSchedulers.mainThread()) // todo 给下游切换 主线程
// 2.注册完成之后,更新注册UI
.subscribe(new Consumer<RegisterResponse>() { // 下游 简化版
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
// 更新注册相关的所有UI
// .....
}
});
// 3.马上去登录服务器操作
MyRetrofit.createRetrofit().create(IRequestNetwork.class)
.loginAction(new LoginRequest()) // Observable<LoginResponse> 上游 被观察者 耗时操作
.subscribeOn(Schedulers.io()) // todo 给上游分配异步线程
.observeOn(AndroidSchedulers.mainThread()) // todo 给下游切换 主线程
// 4.登录完成之后,更新登录的UI
.subscribe(new Consumer<LoginResponse>() { // 下游 简化版
@Override
public void accept(LoginResponse loginResponse) throws Exception {
// 更新登录相关的所有UI
// .....
}
});
}
private ProgressDialog progressDialog;
public void request2(View view) {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("正在执行中...");
/**
* 一行代码 实现需求
* 需求:
* * 1.请求服务器注册操作
* * 2.注册完成之后,更新注册UI
* * 3.马上去登录服务器操作
* * 4.登录完成之后,更新登录的UI
*/
MyRetrofit.createRetrofit().create(IRequestNetwork.class)
// 1.请求服务器注册操作 // todo 第二步 请求服务器 注册操作
.registerAction(new RegisterRequest()) // Observable<RegisterResponse> 上游 被观察者 耗时操作
.subscribeOn(Schedulers.io()) // todo 给上游分配异步线程
.observeOn(AndroidSchedulers.mainThread()) // todo 给下游切换 主线程
// 2.注册完成之后,更新注册UI
/**
* 这样不能订阅,如果订阅了,就无法执行
* 3 马上去登录服务器操作
* 4.登录完成之后,更新登录的UI
*
* 所以我们要去学习一个 .doOnNext(),可以在不订阅的情况下,更新UI
*/
.doOnNext(new Consumer<RegisterResponse>() { // 简单版本的下游
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
// todo 第三步 更新注册相关的所有UI
// 更新注册相关的所有UI
tv_register_ui.setText("xxx");
// .......
}
})
// 3.马上去登录服务器操作 -- 耗时操作
.subscribeOn(Schedulers.io()) // todo 分配异步线程
.flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() {
@Override
public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
// 还可以拿到 注册后的响应对象RegisterResponse
// 执行耗时操作
// 马上去登录服务器操作 -- 耗时操作
Observable<LoginResponse> observable = MyRetrofit.createRetrofit().create(IRequestNetwork.class)
.loginAction(new LoginRequest()); // todo 第四步 马上去登录服务器操作 -- 耗时操作
return observable;
}
})
// 4.登录完成之后,更新登录的UI
.observeOn(AndroidSchedulers.mainThread()) // // todo 给下游切换 主线程
.subscribe(new Observer<LoginResponse>() {
@Override
public void onSubscribe(Disposable d) {
// todo 第一步
progressDialog.show();
}
@Override
public void onNext(LoginResponse loginResponse) {
// 更新登录相关的所有UI
// todo 第五步 更新登录相关的所有UI
tv_login_ui.setText("xxxx");
// ...........
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
// todo 第六步
progressDialog.dismiss(); // 结束对话框 ,整个流程完成
}
});
}
}
方法一是分开来写的,注册和登录分两步写。
方法二是合在一起写的,注册的返回更新UI之后,通过flatMap变换操作符直接去请求登录接口,最终下游接收到的是登录的响应。而注册的响应则是通过doOnNext操作符接收到。flatMap变换操作符也同样可以接收到。
总结
RxJava + Retrofit (请求网络OkHttp ---- Retrofit — Observable)
1.OkHttp 请求网络 (Retorfit)
2.Retorfit 返回一个结果 (Retorfit) — Observable
3.最终的结果 是RxJava中的 被观察者 上游 Observable
4.一行代码写完需求流程: 从上往下
- 1.请求服务器,执行注册操作(耗时)切换异步线程
- 2.更新注册后的所有 注册相关UI - main 切换主线程
- 3.请求服务器,执行登录操作(耗时)切换异步线程
- 4.更新登录后的所有 登录相关UI - main 切换主线程
5.看RxJava另外一种的执行流程
- 初始点 开始点 订阅
- 1.onSubscribe
- 2.registerAction(new RegisterRequest())
- 3…doOnNext 更新注册后的 所有UI
- 4.flatMap执行登录的耗时操作
- 5.订阅的观察者 下游 onNext 方法,更新所有登录后的UI
- 6.progressDialog.dismiss()