Android Rxjava

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


猜你喜欢

转载自blog.csdn.net/haobobo710/article/details/81017133