JavaFx使用RxJava套餐(九)
JavaFx使用RxJava套餐(九)
JavaFx从入门到入土系列
我们知道,在子线程中无法更新UI的,可以使用Platform.runLater(command);
将执行的事件发往主线程更新UI。
那么问题来了,我们异步请求服务器怎么处理?
假设如下场景:在UI中显示服务上线进度
那么你的代码可能是这样
public class JavaFxDemo extends Application {
@Override
public void start(Stage stage) throws Exception {
// 定义一个标签,类似html中的span
Label label = new Label("hello world!");
// 将标签加入场景,场景类似 HTML中的 body, 将span放到body中
// 将场景放到stage中,类似HTML 中的将 body 放到 html标签里一样
stage.setScene(new Scene(label));
// 设置舞台的宽高标题
stage.setWidth(400);
stage.setHeight(100);
stage.setTitle("师姐,你好!");
stage.show();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
// http 同步请求获取服务上线进度
int info= HttpRequest.userClient.getUpInfo();
Platform.runLater(new Runnable() {
@Override
public void run() {
label.setText("上线服务完成:"+info+" %");
}
});
if (info>=100){
break;
}
} catch (Exception e) {
e.printStackTrace();
label.setText("获取进度异常");
break;
}
}
}
}).start();
}
public static void main(String[] args) {
launch(args);
}
}
那么是否可以使用观察者模式来执行呢?这时就用到了RxJava全家桶系列了。
RxJava
首先引入依赖:2021年9月19日22:58:37 最新版 RxJava 2.x
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.2.21</version>
</dependency>
那么代码就改成了下面这样
// 被观察者对象
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
while (true){
int info= HttpRequest.userClient.getUpInfo();
emitter.onNext(info);
if (info>=100){
emitter.onComplete();
break;
}
}
}
}).subscribeOn(Schedulers.io()) //在子线程发射
.observeOn(Schedulers.from(new Executor() {
@Override
public void execute(Runnable command) {
// 将线程执行发往主线程更新UI
Platform.runLater(command);
}
})) //在主线程接收执行更新UI
.subscribe(new Observer<Integer>() {// 观察对象
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
label.setText("上线服务完成:"+integer+" %");
}
@Override
public void onError(Throwable e) {
label.setText("获取进度异常");
}
@Override
public void onComplete() {
}
});
你会疑问,代码变多了。
好吧,我们可以对观察者模式进行进一步封装:
new RxObservableUtils(new ByWatch() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
while (true) {
// http 同步请求获取服务上线进度
int info = HttpRequest.userClient.getUpInfo();
emitter.onNext(info);
if (info >= 100) {
emitter.onComplete();
break;
}
}
}
}).watch(new Watch() {
@Override
public void onNext(Object o) {
label.setText("上线服务完成:" + o + " %");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
label.setText("获取进度异常");
}
});
封装后代码易于理解,特别是要处理业务复杂时
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.schedulers.Schedulers;
import javafx.application.Platform;
import java.util.concurrent.Executor;
/**
* @author lingkang
* @date 2021/9/19 23:06
* @description
*/
public class RxObservableUtils<T> {
private Observable<T> observable;
public RxObservableUtils(ObservableOnSubscribe<T> subscribe, Watch<T> watch) {
Observable.create(subscribe)
.subscribeOn(Schedulers.io()) //在子线程中执行
.observeOn(Schedulers.from(new Executor() {
@Override
public void execute(Runnable command) {
// 将线程执行发往主线程更新UI
Platform.runLater(command);
}
}))//在主线程接收执行更新UI
.subscribe(watch);
}
public RxObservableUtils(ObservableOnSubscribe<T> subscribe, Observer<T> observer) {
Observable.create(subscribe)
.subscribeOn(Schedulers.io()) //在子线程中执行
.observeOn(Schedulers.from(new Executor() {
@Override
public void execute(Runnable command) {
// 将线程执行发往主线程更新UI
Platform.runLater(command);
}
}))//在主线程接收执行更新UI
.subscribe(observer);
}
public RxObservableUtils(ObservableOnSubscribe<T> subscribe) {
observable = Observable.create(subscribe)
.subscribeOn(Schedulers.io()) //在子线程中执行
.observeOn(Schedulers.from(new Executor() {
@Override
public void execute(Runnable command) {
// 将线程执行发往主线程更新UI
Platform.runLater(command);
}
}));//在主线程接收执行更新UI
}
public RxObservableUtils(ByWatch<T> byWatch) {
observable = Observable.create(byWatch)
.subscribeOn(Schedulers.io()) //在子线程中执行
.observeOn(Schedulers.from(new Executor() {
@Override
public void execute(Runnable command) {
// 将线程执行发往主线程更新UI
Platform.runLater(command);
}
}));//在主线程接收执行更新UI
}
public RxObservableUtils watch(Watch<T> w) {
observable.subscribe(w);
return this;
}
}
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
public class ByWatch<T> implements ObservableOnSubscribe<T> {
@Override
public void subscribe(ObservableEmitter<T> emitter) throws Exception {
}
}
继承后按需取用
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
public class Watch<T> extends toWatch<T> {
}
class toWatch<T> implements Observer<T> {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(T t) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
}