上一篇我们完成了一个简单的RxJava2的场景订了一碗牛肉面,这一节我们将要订更多的牛肉面。
1、设定场景。
家里来了100个客人还没过早,这次我要订 100
份牛肉面。
2、代码
//创建一个快餐店。Observable(被观察者)
Observable kuaicandian=Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
for (int i = 0; i < 100; i++) {
Thread.sleep(new Random().nextInt(2000));//随机生成0到2秒的延时
e.onNext("快餐(牛肉面)"+i);//发送数据
}
e.onComplete();//关闭发送数据,以后不能再使用e.onNext
}
});
将上一章的按键1中的代码复制到按键2中,修改上面红色这一段。
仅仅加了一个·for循环,延时时间设为0-2秒随机。
现在运行,点按键2,可以看牛肉面正时快时慢的一碗一碗送来。
3、改进
上面的代码随然成功,但是100碗牛肉面呀,按这个速度,估计后面送到的直接可以当中饭吃,如何加快送餐速度呢。
方法很简单,就是多找几家快餐店呀!
- 第一步
//创建一个快餐2号店。Observable(被观察者)
Observablekuaicandian1
=Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
for (int i = 0; i <10
; i++) {
Thread.sleep(new Random().nextInt(2000));//随机生成0到2秒的延时
e.onNext(“2号
快餐(牛肉面)”+i);//发送数据
}
e.onComplete();//关闭发送数据,以后不能再使用e.onNext
}
});
把创建一个快餐店的代码按上面代码修改。建立两个快餐店,1号店和2号店。
第二步
//把你的地址留给快餐店。subscribe(订阅)
observable.subscribe(wo);这段代码改一成:
//把你的地址留给快餐店。subscribe(订阅)
//这里用merge将1号快餐店和2号快餐店发回的数据合并统一接收,还可以添加3、4…号快餐店
Observable.merge(kuaicandian1,kuaicandian2)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(wo);
看一下运行结果
这个结果是不对的,因为它还是按顺序送的快餐,1号店送完,然后2号店送。
正常情况,两个快餐店同时做牛肉面,一个做好了,另一个也差不多了,因引1号与2号的店的每一份的送餐时间应该是差不多的。
问题出在那里呢?在这里。
.subscribeOn(Schedulers.newThread())
在Observable.merge把两个快餐店合并后,这条语句就把它们转到了一个线程,在同一个线程中,两个for肯定一个先执行一个后执行,所以我们要将两个快餐店放在两个线程中。方法很简单,把这条语句移到
两个快餐店后面,如下。
//创建一个快餐2号店。Observable(被观察者)
Observable kuaicandian1=Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(new Random().nextInt(2000));//随机生成0到2秒的延时
e.onNext(“2号 快餐(牛肉面)”+i);//发送数据
}
e.onComplete();//关闭发送数据,以后不能再使用e.onNext
}
}).subscribeOn(Schedulers.newThread());//移到这里
看一下运行结果
达到要求。
4、改进
上面送来了很多牛肉面,但有20碗吗?会不会有的快餐店漏送了,要监控一下。
a、先声名一个全局变量
int ix=0;
b、再修改onNext内的代码
@Override
public void onNext(String s) {
ix++;
tv.setText(tv.getText()+""+s+"("+ix+")\n");
}
运行结果:
确定有20碗,终于搞定。
结尾:我们还可以在merge中加入更多的快餐店,但是随着快餐店的增多,会不会造成漏送呢?
完整代码:
界面代码:同上一篇
java代码
public class MainActivity extends AppCompatActivity {
private final static String TAG="ggggg";
TextView tv;
int ix=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
}
public void bt1_onClick(View view) {
}
public void bt3_onClick(View view) {
tv.setText("点了按键3");
}
public void bt2_onClick(View view) {
tv.setText("");
//创建1号快餐店。Observable(被观察者)
Observable<String> kuaicandian1=Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(new Random().nextInt(2000));//随机生成0到2秒的延时
e.onNext("1号:快餐(牛肉面)"+i);//发送数据
}
e.onComplete();//关闭发送数据,以后不能再使用e.onNext
}
}).subscribeOn(Schedulers.newThread());
//创建2号快餐店。Observable(被观察者)
Observable<String> kuaicandian2=Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(new Random().nextInt(2000));//随机生成0到2秒的延时
e.onNext("2号:快餐(牛肉面)"+i);//发送数据
}
e.onComplete();//关闭发送数据,以后不能再使用e.onNext
}
}).subscribeOn(Schedulers.newThread());
Observer<String> wo=new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
tv.setText(tv.getText()+"RxJava-开始送快餐"+"\n");
}
@Override
public void onNext(String s) {
ix++;
tv.setText(tv.getText()+""+s+"("+ix+")\n");
}
@Override
public void onError(Throwable e) {
tv.setText(tv.getText()+"RxJava-送快餐出错"+"\n");
}
@Override
public void onComplete() {
tv.setText(tv.getText()+"RxJava-本次快餐送达完毕"+"\n");
}
};
//把你的地址留给快餐店。subscribe(订阅)
//kuaicandian.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(wo);
//这里用merge将1号快餐店和2号快餐店发回的数据合并统一接收,还可以添加3、4...号快餐店
Observable.merge(kuaicandian1,kuaicandian2)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(wo);
}
public void bt4_onClick(View view) {
tv.setText("点了按键4");
}
}