前言
RxJava本质上是一个异步操作库,用极其简洁的逻辑去处理繁琐复杂任务的异步事件库,RxAndroid是基于RxJava开发出的一套适用于Android开发的辅助库。
依赖
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
// rxBinding已经依赖了rxJava,可以无需再重复依赖rxJava
implementation 'com.jakewharton.rxbinding4:rxbinding:4.0.0'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
// (see https://github.com/ReactiveX/RxJava/releases for latest 3.x.x version)
// implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
文档
操作符说明:Operators · ReactiveX文档中文翻译
使用场景
1.应用场景及案例:RxJava实现异步网络数据请求
private void doAsyncTask() {
// 1.延迟创建,通过defer定义被观察者对象,此时被观察者对象还没创建
Observable<String> observable = Observable.defer(new Supplier<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> get() {
// 这里可以做异步任务,例如网络请求
StringBuilder builder = new StringBuilder();
try {
URL url = new URL("https://www.wanandroid.com/banner/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(30 * 1000);
connection.setConnectTimeout(30 * 1000);
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader((new InputStreamReader(inputStream)));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
connection.disconnect();
// 休眠一秒
Thread.sleep(1000);
} catch (Exception ex) {
builder.append(ex.toString());
}
return Observable.just(builder.toString());
}
});
// 2.创建被观察者对象
DisposableObserver observer = new DisposableObserver() {
@Override
public void onNext(Object o) {
if (null != o && o instanceof String) {
String data = (String) o;
try {
String message = data;
if (!TextUtils.isEmpty(data)) {
data = data.trim();
if (data.startsWith("{")) {
JSONObject jsonObject = new JSONObject(data);
message = jsonObject.toString(2);
} else if (data.startsWith("[")) {
JSONArray jsonArray = new JSONArray(data);
message = jsonArray.toString(2);
}
}
tvResult.setText(message);
} catch (Exception e) {
}
}
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
};
// 3.观察者开始订阅 注:此时,才会调用defer()创建被观察者对象(Observable)
Disposable disposable = observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(observer);
mDisposable.add(disposable);
}
2.应用场景及案例:RxJava实现数据缓存优先加载
private void loadData() {
// 第1个被观察者Observable:检查内存缓存是否有数据
Observable<String> memory = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) {
// 判断是否有数据
if (!TextUtils.isEmpty(memoryCache)) {
emitter.onNext(memoryCache);
} else {
emitter.onComplete();
}
}
});
// 第2个被观察者Observable:检查磁盘缓存是否有数据
Observable<String> disk = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 判断是否有数据
if (!TextUtils.isEmpty(diskCache)) {
emitter.onNext(diskCache);
} else {
emitter.onComplete();
}
}
});
// 第3个被观察者Observable:从网络中获取数据,延迟创建,通过defer定义被观察者对象,此时被观察者对象还没创建
Observable<String> network = Observable.defer(new Supplier<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> get() {
// 这里可以做异步任务,例如网络请求
StringBuilder builder = new StringBuilder();
try {
URL url = new URL("https://www.wanandroid.com/banner/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(30 * 1000);
connection.setConnectTimeout(30 * 1000);
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader((new InputStreamReader(inputStream)));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
connection.disconnect();
// 休眠一秒
Thread.sleep(1000);
} catch (Exception ex) {
builder.append(ex.toString());
}
String result = builder.toString();
memoryCache = result;
setDiskCache(result);
return Observable.just(result);
}
});
// 通过concat()合并memory、disk、network 3个被观察者的事件(即检查内存缓存、磁盘缓存 & 网络请求),并将它们按顺序串联成队列
// 通过firstElement()从串联队列中取出并发送第1个有效事件(Next事件),即依次判断检查memory、disk、network,只要其中有一个有效事件,后续事件会停止判断
Observable.concat(memory, disk, network)
.firstElement()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String data) {
try {
String message = data;
if (!TextUtils.isEmpty(data)) {
data = data.trim();
if (data.startsWith("{")) {
JSONObject jsonObject = new JSONObject(data);
message = jsonObject.toString(2);
} else if (data.startsWith("[")) {
JSONArray jsonArray = new JSONArray(data);
message = jsonArray.toString(2);
}
}
tvResult.setText(message);
} catch (Exception e) {
}
}
});
}
3.应用场景及案例:RxJava实现延迟弹窗
private void showDialog() {
Observable.timer(3, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
if (!isFinishing()) {
new AlertDialog.Builder(DialogActivity.this)
.setTitle("自动弹窗")
.setMessage("请对我们进行评价吧~")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).create().show();
}
}
});
}
4.应用场景及案例:RxJava实现秒表计时器
private void startTimer() {
// 周期性执行某个任务
Observable.interval(10, TimeUnit.MILLISECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
mDisposable = d;
}
@Override
public void onNext(@NonNull Long count) {
// 10毫秒一次,1000毫秒100次,count代表次数
long time = count * 10;
long currentMillers = time / 1000;
long minute = currentMillers / 60;
long millers = currentMillers % 60;
String strSeconds;
if (millers < 10) {
strSeconds = "0" + millers;
} else {
strSeconds = String.valueOf(millers);
}
String strMinute;
if (minute < 10) {
strMinute = "0" + minute;
} else {
strMinute = String.valueOf(minute);
}
if (count < 10) {
tvResult.setText(strMinute + ":" + strSeconds + "." + count);
} else {
String string = ("" + count);
String milliSeconds = string.substring(string.length() - 2);
tvResult.setText(strMinute + ":" + strSeconds + "." + milliSeconds);
}
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
5.应用场景及案例:RxJava实现文本框搜索防抖动
private void onTextChangeEvents(EditText editText) {
RxTextView.textChangeEvents(editText)
.debounce(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<TextViewTextChangeEvent>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull TextViewTextChangeEvent textViewTextChangeEvent) {
String text = textViewTextChangeEvent.getText().toString();
// 用于演示
tvResult.setText(text);
// 开始搜索
doSearch(text);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
6.应用场景及案例:RxJava实现防重复点击
private void clicks(View view) {
// 一秒钟之内多次点击只算一次点击
RxView.clicks(view)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) {
mCount = mCount + 1;
tvResult.setText("点击次数:" + mCount);
}
});
}
7.应用场景及案例:RxJava实现需要等待多个接口都获取完数据之后,再同步更新界面
private void doRequest() {
// 被观察者1
Observable<String> observable1 = Observable.defer(new Supplier<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> get() {
// 这里可以做异步任务,例如网络请求
StringBuilder builder = new StringBuilder();
try {
URL url = new URL("https://www.wanandroid.com/banner/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(30 * 1000);
connection.setConnectTimeout(30 * 1000);
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader((new InputStreamReader(inputStream)));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
connection.disconnect();
// 休眠两秒
Thread.sleep(2000);
} catch (Exception ex) {
builder.append(ex.toString());
}
return Observable.just("A:" + builder.toString());
}
});
// 被观察者2
Observable<String> observable2 = Observable.defer(new Supplier<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> get() {
// 这里可以做异步任务,例如网络请求
StringBuilder builder = new StringBuilder();
try {
URL url = new URL("https://www.wanandroid.com/banner/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(30 * 1000);
connection.setConnectTimeout(30 * 1000);
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader((new InputStreamReader(inputStream)));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
connection.disconnect();
} catch (Exception ex) {
builder.append(ex.toString());
}
return Observable.just("B:" + builder.toString());
}
});
// 数据合并
Observable.merge(observable1, observable2).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
@Override
public void accept(String s) {
tvResult.append(s + "\n\n");
}
});
}