java自带的观察者模式
观察者模式定义了对象之间一对多的的依赖关系,以便一个对象的状态发生改变时,所有依赖于他的对象都能够得到通知,并自动刷新。
一、总结
特点
java自带的观察者模式,其观察者和被观察者是在同一个线程。
使用
1、创建被观察者类和观察者接口
创建被观察者类,它继承自java.util.Observable类;
创建观察者类,它实现java.util.Observer接口;
对于被观察者类:
当被观察者中的事件发生变化时,执行
setChanged();
notifyObservers();
setChange()方法用来设置一个内部标志位注明数据发生了变化;notifyObservers()方法会去调用观察者对象列表中所有的Observer的update()方法,通知它们数据发生了变化。
只有在setChange()被调用后,notifyObservers()才会去调用update()。
对于观察者类:
实现Observer接口的唯一方法update
void update(Observable o, Object arg)
形参Object arg,对应一个由notifyObservers(Object arg);传递来的参数,当执行的是notifyObservers();时,arg为null。
2、数据交互
2.1 被观察者添加观察者订阅
2.2 被观察者数据改变,更新数据;并通知观察者
2.3 观察者接受到被观察者的通知,来更新自己的数据操作
2.4 观察者从被观察者队列中移除
二、举例
1、被观察者类
DataChange
public class DataChange extends Observable {
private static DataChange instance = null;
public static DataChange getInstance() {
if (null == instance) {
instance = new DataChange();
}
return instance;
}
public void notifyDataChange(Data data) {
setChanged();
notifyObservers(data);
}
}
2、观察者接口
DataWatcher
public abstract class DataWatcher implements Observer {
@Override
public void update(Observable observable, Object data) {
}
}
3、被观察者类要改变的databean
public class Data {
private int data;
public Data() {
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
4、完成被观察者和观察者订阅/解订阅的过程
public class ObserverActivity extends Activity {
TextView showchange;
int change = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_observer);
showchange = findViewById(R.id.showchange);
Button change0 = findViewById(R.id.change0);
change0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//被观察者数据改变,更新数据;并通知观察者
Data mData = new Data();
mData.setData(change++);
DataChange.getInstance().notifyDataChange(mData);
}
});
}
@Override
protected void onResume() {
super.onResume();
//被观察者添加观察者订阅
DataChange.getInstance().addObserver(watcher);
}
@Override
protected void onPause() {
super.onPause();
//观察者从被观察者队列中移除
DataChange.getInstance().deleteObserver(watcher);
}
private DataWatcher watcher = new DataWatcher() {
@Override
public void update(Observable observable, Object data) {
super.update(observable, data);
//观察者接受到被观察者的通知,来更新自己的数据操作。
Data mData = (Data) data;
Log.e("060", "mData---->>" + mData.getData() + ", threadid---->>" + Thread.currentThread().getId());
showchange.setText(mData.getData() + "");
}
};
}
Android观察者模式Rxjava
一、总结
达成效果:异步+观察者模式
rxjava要理解三个概念就够了,一个是观察者Observer,另一个是订阅者Subscribe,,最后一个线程控制调度器Scheduler。
观察者Observer
订阅者Subscribe
线程控制调度器Scheduler
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。
二、被观察者事件产生
create() 方法是 RxJava 最基本的创造事件序列的方法。
Observable<String> myObservable1 = Observable.create( //被观察者。。create() 方法是 RxJava 最基本的创造事件序列的方法。
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> sub) {
// TODO:
Log.e("060", "myObservable1 thread id : " + Thread.currentThread().getId());
sub.onNext("Hello, world!"); // 写回调,传给观察者
sub.onCompleted(); //订阅事件全部结束后的回调,传给观察者
}
}
);
RxJava 还提供了一些方法用来快捷创建事件队列,例如:just(T...): 将传入的参数依次发送出来。
1、just
// Observable<String> observable = Observable.just("hello");
Observable<String> observable = Observable.just("hello", "my", "nice", "world");
Subscription subscription = observable.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
Log.e("060", "onNext : " + s);
}
});
2、form
List<Integer> lists = new ArrayList<>(); //from(T[]) / from(Iterable<? extends T>) : 将传入的数组或 Iterable 拆分成具体对象后,依次发送出来。
lists.add(1);
lists.add(2);
lists.add(3);
lists.add(4);
lists.add(5);
Observable<Integer> observable = Observable.from(lists);
三、观察者重写
Subscriber<String> mySubscriber1 = new Subscriber<String>() { //观察者
@Override
public void onNext(String s) {
Log.e("060", "mySubscriber1 thread id : " + Thread.currentThread().getId());
Log.e("010", s + "");
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
};
//观察者
Action1<String> onNextAction = new Action1<String>() {
@Override
public void call(String s) {
Log.e("060", s + ": 21");
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
@Override
public void call(Throwable s) {
}
};
Action0 onCompleteAction = new Action0() {
@Override
public void call() {
}
};
四、Scheduler
Scheduler 的 API
在RxJava 中,Scheduler ——调度器,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景:
Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。
有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。 * subscribeOn(): 指定subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。 * observeOn(): 指定Subscriber 所运行在的线程。或者叫做事件消费的线程。
* 线程控制Scheduler
*/
public void test1() {
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。
.observeOn(AndroidSchedulers.mainThread()) // 指定Subscriber 所运行在的线程。或者叫做事件消费的线程。
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.e(tag, "number:" + number + "; threadid is :" + Thread.currentThread().getId());
}
});
}
public void test2() {
Observable.just("ha1", "ha2", "ha3", "ha4")
.subscribeOn(Schedulers.io()) // 指定subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。
.observeOn(AndroidSchedulers.mainThread()) // 指定Subscriber 所运行在的线程。或者叫做事件消费的线程。
.subscribe(new Action1<String>() {
@Override
public void call(String str) {
Log.e(tag, "str:" + str + "; threadid is :" + Thread.currentThread().getId());
}
});
}
观察者与被观察者订阅:
//方式一
public void startSubscribe1() { //订阅
myObservable1.subscribe(mySubscriber1);
}
Observable<String> myObservable1 = Observable.create( //被观察者。。create() 方法是 RxJava 最基本的创造事件序列的方法。
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> sub) {
// TODO:
Log.e("060", "myObservable1 thread id : " + Thread.currentThread().getId());
sub.onNext("Hello, world!"); // 写回调,传给观察者
sub.onCompleted(); //订阅事件全部结束后的回调,传给观察者
}
}
);
Subscriber<String> mySubscriber1 = new Subscriber<String>() { //观察者
@Override
public void onNext(String s) {
Log.e("060", "mySubscriber1 thread id : " + Thread.currentThread().getId());
Log.e("010", s + "");
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
};
//方式二
public void startSubscribe21() {
myObservable2.subscribe(onNextAction, onErrorAction,onCompleteAction); //RxJava 还提供了一些方法用来快捷创建事件队列,例如:just(T...): 将传入的参数依次发送出来。
}
Observable<String> myObservable2 = Observable.just("Hello, world!"); //被观察者
//观察者
Action1<String> onNextAction = new Action1<String>() {
@Override
public void call(String s) {
Log.e("060", s + ": 21");
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
@Override
public void call(Throwable s) {
}
};
Action0 onCompleteAction = new Action0() {
@Override
public void call() {
}
};
//方式三
public void startSubscribe22() {
Observable.just("Hello, world!")
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e("060", s + ": 22");
}
});
}
五、举例
源码地址:
https://github.com/yuanhhyuan/RxjavaSample