事件总线框架大家应该都用过不少,从最开始的otto到Eventbus,再到Rxbus,这些开源框架都应用到了一个经典的设计模式-观察者模式。使用中,最直观的体验就是不用再去写那些繁琐的回调代码,模块和业务之间的耦合度也会极大程度地降低。
其实在Android源码中,观察者模式的使用无处不在,应用最广泛、典型的要数ListView和RecyclerView中的Adapter了。下面我们从RecyclerView.Adapter的源码中,分析它的观察者模式是如何实现的。
- 首先从我们经常调用到的notifyDataSetChanged入手,这是一个通知数据改变,刷新界面布局的方法
public abstract static class Adapter<VH extends ViewHolder> {
//被观察者
private final AdapterDataObservable mObservable = new AdapterDataObservable();
/**
* 注册观察者,监听数据集的变化
*/
public void registerAdapterDataObserver(AdapterDataObserver observer) {
mObservable.registerObserver(observer);
}
/**
* 取消注册,不再监听数据集的改变
*/
public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
mObservable.unregisterObserver(observer);
}
/**
* 通知注册的观察者数据集发生改变
*/
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
}
- 实际调用的是AdapterDataObservable.notifyChanged()
static class AdapterDataObservable extends Observable<AdapterDataObserver> {
public void notifyChanged() {
//调用所有观察者的onChanged方法
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
- 来到AdapterDataObserver中,调用其onChanged方法
public abstract static class AdapterDataObserver {
public void onChanged() {
// Do nothing
}
}
- 可以看到上面是一个抽象类,具体实现看其子类RecyclerViewDataObserver,这里就是观察者收到消息通知后的具体实现
private class RecyclerViewDataObserver extends AdapterDataObserver {
//上面说到的所有观察者onChanged方法的核心实现
@Override
public void onChanged() {
//确保RecyclerView没有在layout或者滑动状态
assertNotInLayoutOrScroll(null);
mState.mStructureChanged = true;
//被观察者收到数据发生改变后的具体实现
setDataSetChangedAfterLayout();
if (!mAdapterHelper.hasPendingUpdates()) {
//重新布局RecyclerView组件
requestLayout();
}
}
}
其实到这一步观察者模式中事件的通知方式已经实现,想进一步探究是如何实现的可以继续深入,看看setDataSetChangedAfterLayout()方法
- 那么问题来了,这里的观察者们是在哪里注册的呢?找到RecyclerView的setAdapter()方法
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2 {
public void setAdapter(Adapter adapter) {
// bail out if layout is frozen
setLayoutFrozen(false);
//具体实现
setAdapterInternal(adapter, false, true);
requestLayout();
}
- 这里也只是包了一层,修改了状态,具体的实现看setAdapterInternal(adapter, false, true),注意关键点adapter.registerAdapterDataObserver(mObserver);
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,
boolean removeAndRecycleViews) {
if (mAdapter != null) {
//首先反注册掉所有观察者
mAdapter.unregisterAdapterDataObserver(mObserver);
mAdapter.onDetachedFromRecyclerView(this);
}
if (!compatibleWithPrevious || removeAndRecycleViews) {
removeAndRecycleViews();
}
mAdapterHelper.reset();
final Adapter oldAdapter = mAdapter;
mAdapter = adapter;
if (adapter != null) {
//注册新的观察者
adapter.registerAdapterDataObserver(mObserver);
adapter.onAttachedToRecyclerView(this);
}
if (mLayout != null) {
mLayout.onAdapterChanged(oldAdapter, mAdapter);
}
mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);
mState.mStructureChanged = true;
setDataSetChangedAfterLayout();
}
- 继续探究RecyclerView中registerAdapterDataObserver的具体实现
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2 {
public void registerAdapterDataObserver(AdapterDataObserver observer) {
mObservable.registerObserver(observer);
}
}
- 看一下mObservable是什么
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();
}
}
}
到此,我们就知道了观察者们是在RecyclerView的setAdapter的调用过程中被注册的。总的看来,观察者模式的实现原理是维护一个集合,添加或删除集合元素实现观察者的注册与反注册,遍历集合,调用元素的方法实现消息的推送
网友评论