首先声明:虽然在ViewPager(充当观察者)和PagerAdapter(充当被观察者)中出现了观察者模式的代码,但是ViewPager中并未注册观察者。不过这里的案例非常经典,不由得分析下作为记录。同样的,ListView(充当观察者)和BaseAdapter(充当被观察者)则使用了这个模式并在ListView中注册了观察者,有兴趣的可以查看相关源码。
前面讲了一个伪观察者模式,继续....
仍然是上次的代码,notifyDataSetChanged最后一行调用了
mObservable.notifyChanged() 这才是正宗的观察者模式。
public abstract class PagerAdapter {
// 被观察者
private final DataSetObservable mObservable = new DataSetObservable();
public void notifyDataSetChanged() {
synchronized (this) {
// 冒充者
if (mViewPagerObserver != null) {
mViewPagerObserver.onChanged();
}
}
// 正宗
mObservable.notifyChanged();
}
public void registerDataSetObserver(DataSetObserver observer) {
mObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mObservable.unregisterObserver(observer);
}
}
如何在PagerAdapter 中给 被观察者DataSetObservable 注册一个观察者?
注意:这段代码仅做参考,Android并未真正注册。
PagerAdapter pagerAdapter = new .. ;
pagerAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
// .... 实现,这里copy伪娘那里的onChange()方法.
}
@Override
public void onInvalidated() {
super.onInvalidated();
// .... 实现
}
});
下面我们就来一起看看Android的被观察者和观察者是怎么写的,可以借鉴参考下:
被观察者
DataSetObservable
public class DataSetObservable extends Observable<DataSetObserver> {
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
public void notifyInvalidated() {
synchronized (mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onInvalidated();
}
}
}
}
Observable
package android.database;
import java.util.ArrayList;
public abstract class Observable<T> {
protected final ArrayList<T> mObservers = new ArrayList<T>();
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)) {
throw new IllegalStateException("Observer " + observer + " is already registered.");
}
mObservers.add(observer);
}
}
public void unregisterObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
int index = mObservers.indexOf(observer);
if (index == -1) {
throw new IllegalStateException("Observer " + observer + " was not registered.");
}
mObservers.remove(index);
}
}
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
观察者
package android.database;
public abstract class DataSetObserver {
public void onChanged() {
// Do nothing
}
public void onInvalidated() {
// Do nothing
}
}
这就是Android经典的观察者模式.
源码扩展ListView和ViewPager在适配器模式和观察者模式存在诸多相似,举一反三让我们的理解更加透彻。
ListView在setAdapter() 中注册的观察者.
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
super.setAdapter(adapter);
if (mAdapter != null) {
// 注册观察者
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
}
requestLayout();
}