说明
该文档不是介绍如何使用RxJava,如要详细地使用RxJava请参考下面的参考文档。整个文档比较抽象,说明得不够细致,如果有不明白的地方可以查看其他文档或者评论区交流。建议先结合使用文档再浏览该文档,并且细读,希望能给大家提供帮助。
参考文档
入门
- [RxJava2.0——从放弃到入门
- www.cnblogs.com/lyysz/p/634…
- 【知识整理】这可能是最好的RxJava 2.x 入门教程(一)
- RxJava入门之介绍与基本运用
- RxJava入门
基础相关
RxJava2.0与RxJava3.0差异化
1.RxJava应用场景
核心思想
传统思维
// 传统方式 思维 无法固定 (后面接手你写的项目,看不懂)
// A程序员:35356453 自己的思维 不同 封装方法....
// B程序员:46576576 自己的思维 不同 全部写在一起
// C程序员:43643654 自己的思维 不同 new Thread
// D程序员:66545655 自己的思维 不同 使用 线程池
// ...
// 零零散散 麻烦 思维
public void downloadImageAction(View view) {
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("下载图片中...");
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(PATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Message message = handler.obtainMessage();
message.obj = bitmap;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private final Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
Bitmap bitmap = (Bitmap) msg.obj;
image.setImageBitmap(bitmap);
if (progressDialog != null) progressDialog.dismiss();
return false;
}
});
RxJava思维
/**
* 封装我们的操作
* upstream 上游
* d
*/
public final static <UD> ObservableTransformer<UD, UD> rxud() {
return new ObservableTransformer<UD, UD>() {
@Override
public ObservableSource<UD> apply(Observable<UD> upstream) {
return upstream.subscribeOn(Schedulers.io()) // 给上面代码分配异步线程
.observeOn(AndroidSchedulers.mainThread()) // 给下面代码分配主线程;
.map(new Function<UD, UD>() {
@Override
public UD apply(UD ud) throws Exception {
Log.d(TAG, "apply: 我监听到你了,居然再执行");
return ud;
}
});
// ..... ;
}
};
}
public void rxJavaDownloadImageAction(View view) {
// 起点
Observable.just(PATH) // 内部会分发 PATH Stirng // TODO 第二步
// TODO 第三步
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Exception {
URL url = new URL(PATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
return null;
}
})
/*.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
Paint paint = new Paint();
paint.setTextSize(88);
paint.setColor(Color.RED);
return drawTextToBitmap(bitmap, "水印",paint, 88 , 88);
}
})*/
// 日志记录
.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
Log.d(TAG, "apply: 是这个时候下载了图片啊:" + System.currentTimeMillis());
return bitmap;
}
})
.compose(rxud())
// 订阅 起点 和 终点 订阅起来
.subscribe(
// 终点
new Observer<Bitmap>() {
// 订阅开始
@Override
public void onSubscribe(Disposable d) {
// 预备 开始 要分发
// TODO 第一步
progressDialog = new ProgressDialog(DownloadActivity.this);
progressDialog.setTitle("download run");
progressDialog.show();
}
// TODO 第四步
// 拿到事件
@Override
public void onNext(Bitmap bitmap) {
image.setImageBitmap(bitmap);
}
// 错误事件
@Override
public void onError(Throwable e) {
}
// TODO 第五步
// 完成事件
@Override
public void onComplete() {
if (progressDialog != null)
progressDialog.dismiss();
}
});
}
RxJava配合Retrofit
private api = HttpUtil.getOnlineCookieRetrofit().create(WangAndroidApi.class);
/**
* TODO Retrofit+RxJava 查询 项目分类 (总数据查询)
*
* @param view
*/
public void getProjectAction(View view) {
// 获取网络API
api.getProject()
.subscribeOn(Schedulers.io()) // 上面 异步
.observeOn(AndroidSchedulers.mainThread()) // 下面 主线程
.subscribe(new Consumer<ProjectBean>() {
@Override
public void accept(ProjectBean projectBean) throws Exception {
Log.d(TAG, "accept: " + projectBean); // UI 可以做事情
}
});
}
/**
* TODO Retrofit+RxJava 查询 项目分类的49 去 获取项目列表数据 (Item)
*
* @param view
*/
public void getProjectListAction(View view) {
// 注意:这里的 294 是项目分类 所查询出来的数据
// 上面的项目分类会查询出:"id": 294,"id": 402,"id": 367,"id": 323,"id": 314, ...
// id 写死的
api.getProjectItem(1, 294)
// .....可以添加其他操作
.subscribeOn(Schedulers.io()) // 上面 异步
.observeOn(AndroidSchedulers.mainThread()) // 下面 主线程
.subscribe(data->{
Log.d(TAG, "getProjectListAction: " + data);
});
}
public interface WangAndroidApi {
// 总数据
@GET("project/tree/json")
Observable<ProjectBean> getProject(); // 异步线程 耗时操作
// ITem数据
@GET("project/list/{pageIndex}/json") // ?cid=294
Observable<ProjectItem> getProjectItem(@Path("pageIndex") int pageIndex, @Query("cid") int cid); // 异步线程 耗时操作
}
public class HttpUtil {
private static final String TAG = "HttpUtils";
/**
* 默认 test-a环境
*/
public static String BASE_URL = "https://www.wanandroid.com/";
public static void setBaseUrl(String baseUrl) {
BASE_URL = baseUrl;
}
/**
* 根据各种配置创建出Retrofit
*
* @return 返回创建好的Retrofit
*/
public static Retrofit getOnlineCookieRetrofit() {
// OKHttp客户端
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
// 各种参数配置
OkHttpClient okHttpClient = httpBuilder
.addNetworkInterceptor(new StethoInterceptor())
.readTimeout(10000, TimeUnit.SECONDS)
.connectTimeout(10000, TimeUnit.SECONDS)
.writeTimeout(10000, TimeUnit.SECONDS)
.build();
return new Retrofit.Builder().baseUrl(BASE_URL)
// TODO 请求用 OKhttp
.client(okHttpClient)
// TODO 响应RxJava
// 添加一个json解析的工具
.addConverterFactory(GsonConverterFactory.create(new Gson()))
// 添加rxjava处理工具
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}
防抖
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' // 操作功能防抖
/**
* RxJava
* RxJs
* Rxxxxx
* RxBinding 防抖
*
* TODO 功能防抖 + 网络嵌套(这种是负面教程,嵌套的太厉害了)
* 2层嵌套
* 6层
*/
@SuppressLint("CheckResult")
private void antiShakeActon() {
// 注意:(项目分类)查询的id,通过此id再去查询(项目列表数据)
// 对那个控件防抖动?
Button bt_anti_shake = findViewById(R.id.bt_anti_shake);
RxView.clicks(bt_anti_shake)
.throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
api.getProject() // 查询主数据
.compose(DownloadActivity.rxud())
.subscribe(new Consumer<ProjectBean>() {
@Override
public void accept(ProjectBean projectBean) throws Exception {
for (ProjectBean.DataBean dataBean : projectBean.getData()) { // 10
// 查询item数据
api.getProjectItem(1, dataBean.getId())
.compose(DownloadActivity.rxud())
.subscribe(new Consumer<ProjectItem>() {
@Override
public void accept(ProjectItem projectItem) throws Exception {
Log.d(TAG, "accept: " + projectItem); // 可以UI操作
}
});
}
}
});
}
});
}
网络嵌套
起点可以分发一个数据
onNext(1);
|
|
|
flatMap 自己分发 10个数据 给下面,不用for循环处理
1 --> 多发送 10次 1+"DDD"
|
|
|
subscribe{
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
1+"DDD"
}
/**
* TODO 功能防抖 + 网络嵌套 (解决嵌套的问题) flatMap
*/
@SuppressLint("CheckResult")
private void antiShakeActonUpdate() {
// 注意:项目分类查询的id,通过此id再去查询(项目列表数据)
// 对那个控件防抖动?
Button bt_anti_shake = findViewById(R.id.bt_anti_shake);
RxView.clicks(bt_anti_shake)
.throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次
// 我只给下面 切换 异步
.observeOn(Schedulers.io())
.flatMap(new Function<Object, ObservableSource<ProjectBean>>() {
@Override
public ObservableSource<ProjectBean> apply(Object o) throws Exception {
return api.getProject(); // 主数据
}
})
// 第一步不能map 因为 api Observbale<Bean> TODO 小作业 同学们自己尝试
/*.map(new Function<Object, ObservableSource<ProjectBean>>() {
@Override
public ObservableSource<ProjectBean> apply(Object o) throws Exception {
return api.getProject(); // 主数据;
}
})*/
.flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataBean>>() {
@Override
public ObservableSource<ProjectBean.DataBean> apply(ProjectBean projectBean) throws Exception {
return Observable.fromIterable(projectBean.getData()); // 我自己搞一个发射器 发多次 10
}
})
.flatMap(new Function<ProjectBean.DataBean, ObservableSource<ProjectItem>>() {
@Override
public ObservableSource<ProjectItem> apply(ProjectBean.DataBean dataBean) throws Exception {
return api.getProjectItem(1, dataBean.getId());
}
})
.observeOn(AndroidSchedulers.mainThread()) // 给下面切换 主线程
.subscribe(new Consumer<ProjectItem>() {
@Override
public void accept(ProjectItem projectItem) throws Exception {
// 如果我要更新UI 会报错2 不会报错1
Log.d(TAG, "accept: " + projectItem);
}
});
}
doOnNext运用
频繁切换异步线程和UI线程
核心:doOnNext 返回的是obserable,可以继续做事情
需求
- 请求服务器注册操作
- 注册完成之后,更新注册UI
- 马上去登录服务器操作
- 登录完成之后,更新登录的UI
/**
* TODO
* Retrofit + RxJava
* wy.RxJava配合Retrofit。
* RxJava + Retrofit (请求网络OkHttp ---- Retorfit --- 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()
*/
public class RequestActivity extends AppCompatActivity {
private final String TAG = RequestActivity.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_request);
tv_register_ui = findViewById(R.id.tv_login_ui);
tv_login_ui = findViewById(R.id.tv_login_ui);
}
// TODO 方式一 分开写
@SuppressLint("CheckResult")
public void request(View view) {
// 1.请求服务器注册操作
// 2.注册完成之后,更新注册UI
MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
.registerAction(new RegisterRequest())
.compose(DownloadActivity.rxud())
.subscribe(new Consumer<RegisterResponse>() {
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
// 更新注册相关的所有UI
// .....
}
});
// 分开写
// 3.马上去登录服务器操作
// 4.登录完成之后,更新登录的UI
MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
.loginAction(new LoginReqeust())
.compose(DownloadActivity.rxud())
.subscribe(new Consumer<LoginResponse>() {
@Override
public void accept(LoginResponse loginResponse) throws Exception {
// 更新登录相关的所有UI
// .....
}
});
}
/**
* TODO ================= 下面是一行代码完成整个需求
*/
private ProgressDialog progressDialog;
Disposable disposable;
public void request2(View view) {
/**
* 一行代码 实现需求
* 需求:
* 还有弹出加载
* * 1.请求服务器注册操作
* * 2.注册完成之后,更新注册UI
* * 3.马上去登录服务器操作
* * 4.登录完成之后,更新登录的UI
*/
MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
.registerAction(new RegisterRequest()) // todo 1.请求服务器注册操作 // todo 2
.subscribeOn(Schedulers.io()) // 给上面 异步
.observeOn(AndroidSchedulers.mainThread()) // 给下面分配主线程
.doOnNext(new Consumer<RegisterResponse>() { // todo 3,返回的是obserable,可以继续做事情
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
// todo 2.注册完成之后,更新注册UI
}
})
// todo 3.马上去登录服务器操作
.observeOn(Schedulers.io()) // 给下面分配了异步线程
.flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() { // todo 4
@Override
public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
Observable<LoginResponse> loginResponseObservable = MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
.loginAction(new LoginReqeust());
return loginResponseObservable;
}
})
.observeOn(AndroidSchedulers.mainThread()) // 给下面 执行主线程
.subscribe(new Observer<LoginResponse>() {
// 一定是主线程,为什么,因为 subscribe 马上调用onSubscribe
@Override
public void onSubscribe(Disposable d) {
// TODO 1
progressDialog = new ProgressDialog(RequestActivity.this);
progressDialog.show();
// UI 操作
disposable = d;
}
@Override
public void onNext(LoginResponse loginResponse) { // todo 5
// TODO 4.登录完成之后,更新登录的UI
}
@Override
public void onError(Throwable e) {
}
// todo 6
@Override
public void onComplete() {
// 杀青了
if (progressDialog != null) {
progressDialog.dismiss();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 必须这样写,最起码的标准
if (disposable != null)
if (!disposable.isDisposed())
disposable.dispose();
}
}
2.RxJava模式与原理
标准观察者
// 被观察者 实现
public class WechatServerObservable implements Observable {
// 容器 存储 多个 观察者
private List<Observer> observers = new ArrayList<>();
private String message;
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
// 遍历容器
for (Observer observer : observers) {
observer.update(message);
}
}
@Override
public void pushMessage(String message) {
this.message = message;
// System.out.println("微信服务号更新了消息:" + message);
// 通知所有 关注了 此服务号的 用户
notifyObservers();
}
}
RxJava Hook 点
RxJava 1.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
// 提前预留 给 2.x
return source;
}
RxJava 2.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
默认情况下,f == null onObservableAssembly
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
结论:很多很多操作符 都会经过 【onAssembly监听】
map变换操作符原理
public class SourceActivity1 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
// 我想用了多少给 Map操作 flatMap
// Hook之前的监听
RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
@Override
public Observable apply(Observable observable) throws Exception {
Log.d(Flag.TAG, "apply: 整个项目 全局 监听 到底有多少地方使用 RxJava:" + observable);
// 伪代码
/*if (observable === ObservableMap)
return null;*/
return null; // 不破坏人家的功能
}
});
testHook();
}
/**
* TODO RxJava Hook 点
*/
public static void testHook() {
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
e.onNext("A");
}
})
// null.map
.map(new Function<Object, Boolean>() {
@Override
public Boolean apply(Object o) throws Exception {
return true;
}
})
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
}
}) ;
}
}
RxJava的观察者模式
创建Observer
/**
* TODO RxJava的观察者模式
* 1:Observer 源码看看
* 2:Observable创建过程 源码分析
* 3:subscribe订阅过程 源码分析
*/
public class SourceActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 结论: new ObservableCreate() {source == 自定义source}
// 2:Observable创建过程 源码分析
Observable.create(
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 发射器.onNext
emitter.onNext("A");
}
})
// 3:subscribe订阅过程 源码分析
// ObservableCreate. subscribe
.subscribe(
// 自定义观察者
// 1:Observer 源码看看
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
创建Observable
Observable创建过程时 重要的点记录:
Observable创建过程时序图如下:
使用subcribe()订阅
Observable 与 Observer 订阅的过程 重要的点记录:
Observable 与 Observer 订阅的过程 重要步骤:
Observable 与 Observer 订阅的过程时序图如下:
标准观察者模式 与 RxJava观察者模式对比
从模式角度分析 标准观察者模式 与 RxJava观察者模式
Map变换操作符原理
Map源码分析
public class SourceActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ObseravbleCreate 自定义source传递进去了 == source
Observable.create(
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
}
})
// ObseravbleCreate.map
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Exception {
return null;
}
})
// ObservableMap.subscribe
.subscribe(
// 自定义观察者(终点)
new Observer<Bitmap>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Bitmap bitmap) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
一个Map源码分析
RxJava装饰模型
Map的装饰模型
public class SourceActivity4 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("Derry");
e.onComplete();
}
})
// ↓ObservableCreate.map 包裹模型中 最里面
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return 45454;
}
})
// ObservableMap.map
.map(new Function<Integer, Boolean>() {
@Override
public Boolean apply(Integer integer) throws Exception {
return true;
}
})
// ↓包裹模型中最外面 往上走↑的时候在一层 层的剥开
// ObservableMap.subscribe
.subscribe(new Observer<Boolean>() {
@Override
public void onSubscribe(Disposable d) { }
@Override
public void onNext(Boolean bool) {
Log.d(Flag.TAG, "onNext bool:" + bool);
}
@Override
public void onError(Throwable e) { }
@Override
public void onComplete() { }
});
}
}
背压:我生产的速度快过你消费的速度
private void t() {
// 自己去查询
// Flowable.create
// single(只能发射单个) Observable的简化版 Observable完整版(多个 单个)
// 背压
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
while (true) { //不停的发送
e.onNext("A");
}
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
// Thread.sleep(5000); // 五秒后 消费下
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
3.RxJava原理
### 线程切换原理
在Android中RxJava和RxAndroid两个要一起用
// 依赖RxAndroid 2X 的依赖库
// 增加RxJava 2X 的依赖库
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.0.7'
// RxAndroid有什么用
private void test00() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
})
.observeOn(Schedulers.io()) // rxjava
.subscribeOn(AndroidSchedulers.mainThread()) // rxandroid
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
})
;
}
private Disposable disposable;
private void test01() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onNext(String s) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
// ---
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {}
});
}
// 处理报黄
private void test02() {
disposable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("Derry");
e.onNext("A");
e.onComplete();
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 最起码的写法
if (disposable != null)
if (!disposable.isDisposed())
disposable.dispose();
}
subscribeOn() 源码分析
subscribeOn 给上面代码分配线程
public class RxJavaThreadSource1 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Hook IO 传递进去的Hook
RxJavaPlugins.setIoSchedulerHandler(new Function<Scheduler, Scheduler>() {
@Override
public Scheduler apply(Scheduler scheduler) throws Exception {
Log.d(L.TAG, "apply: 全局 监听 scheduler:" +scheduler);
return scheduler;
}
});
// TODO hook 给 IO 初始化
RxJavaPlugins.setInitIoSchedulerHandler(new Function<Callable<Scheduler>, Scheduler>() {
@Override
public Scheduler apply(Callable<Scheduler> schedulerCallable) throws Exception {
Log.d(L.TAG, "apply: 全局 监听 init scheduler:" +schedulerCallable.call());
return schedulerCallable.call();
}
});
Observable.create(
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("Derry");
Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
}
})
// ObservbaleCreate.subscribeOn
// TODO 第二步 new IOScheduler ---> 线程池 传递进去
.subscribeOn(
// TODO 第一步 到底干了什么 ( new IOScheduler ---> 线程池)
Schedulers.io() // 耗时读取的异步
// Schedulers.newThread() // 开启新线程
)
// A线程. subscribe
// ObservableSubscribeOn.subscribe
.subscribe(
// 终点
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Disposable disposable = d;
Log.d(L.TAG, "onSubscribe: " + Thread.currentThread().getName());
}
@Override
public void onNext(String s) {
Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
observeOn
observeOn 给下面代码分配线程
public class RxJavaThreadSource2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(){
@Override
public void run() {
super.run();
test();
}
}.start();
}
private void test() {
Observable.create(
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("Derry");
Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
}
})
// TODO 第二步骤
.observeOn(
// TODO 第一步 主线程的 Handlnr
AndroidSchedulers.mainThread()
)
// subsceOn(1) // 会显示是这个线程的原因,上一层卡片是被1线程执行
// subsceOn(2)
// subsceOn(3)
// observeOn(A)
// observeOn(B)
// observeOn(C) // 终点是被C执行
// ObservableObserveOn.subscribe
.subscribe(
// 终点
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(L.TAG, "onSubscribe: " + Thread.currentThread().getName());
}
@Override
public void onNext(String s) {
Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
private void t() {
new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// UI 操作 ...
}
};
new Thread(){
@Override
public void run() {
super.run();
new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// UI 操作 ... 百分之百 Ui线程 没有问题
}
};
}
}.start();
new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
return false;
}
});
}
}
Schedulers的分类
调度器类型 | 效果 |
---|---|
Schedulers.computation() | 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量 |
Schedulers.from(executor) | 使用指定的Executor作为调度器 |
Schedulers.immediate( ) | 在当前线程立即开始执行任务 |
Schedulers.io( ) | 用于IO密集型任务 |
Schedulers.newThread( ) | 为每个任务创建一个新线程 |
Schedulers.trampoline( ) | 当其它排队的任务完成后,在当前线程排队开始执行 |
AndroidSchedulers.mainThread() | 用于Android的UI更新操作 |
4.自定义RxView操作符
ViewClickObservable
public class ViewClickObservable extends Observable<Object> {
private final View view;
// 事件 第一节课 防抖 事件 没用
private static final Object EVENT = new Object();
private static Object EVENT2;
public ViewClickObservable(View view) {
this.view = view;
EVENT2 = view;
}
@Override
protected void subscribeActual(Observer<? super Object> observer) {
// 可以干自己的
MyListener myListener = new MyListener(view, observer);
observer.onSubscribe(myListener);
this.view.setOnClickListener(myListener);
}
// 我们的包裹
static final class MyListener implements View.OnClickListener, Disposable {
private final View view;
private Observer<Object> observer; // 存一份 下一层
// 原子性,同学们自行看看文章
// https://www.jianshu.com/p/8a44d4a819bc
// boolean == AtomicBoolean
private final AtomicBoolean isDisposable = new AtomicBoolean();
public MyListener(View view, Observer<Object> observer) {
this.view = view;
this.observer = observer;
}
@Override
public void onClick(View v) {
if (isDisposed() == false) {
observer.onNext(EVENT);
}
}
// 如果用调用了 中断
@Override
public void dispose() {
// 如果没有中断过,才有资格, 取消view.setOnClickListener(null);
if (isDisposable.compareAndSet(false, true)) {
// 主线程 很好的中断
if (Looper.myLooper() == Looper.getMainLooper()) {
view.setOnClickListener(null);
} else { // 主线程,通过Handler的切换
/*new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
view.setOnClickListener(null);
};*/
// HandlerScheduler.scheduleDirect
AndroidSchedulers.mainThread().scheduleDirect(new Runnable() {
@Override
public void run() {
view.setOnClickListener(null);
}
});
}
}
}
@Override
public boolean isDisposed() {
return isDisposable.get();
}
}
}
RxView
public class RxView {
private final static String TAG = RxView.class.getSimpleName();
// 我们自己的操作符 == 函数
public static Observable<Object> clicks(View view) {
return new ViewClickObservable(view);
}
}
public class RxActivity extends AppCompatActivity {
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rx);
// 给这个控件做防抖
Button button = findViewById(R.id.button);
RxView.clicks(button)
.throttleFirst(2000, TimeUnit.MILLISECONDS)
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("Derry");
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(L.TAG, "accept: 终点:" + s);
}
});
}
});
}
}