Android Listview 中的观察者模式图示与代码分析

在这里插入图片描述

代码分析:
参与其中的总共八个对象,分别是ListviewAbsListViewArrayAdapterBaseAdapterAdapterDataSetObserverDataSetObserverDataSetObservableObservable

四个抽象对象,四个实体对象。

  1. 首先,DataSetObserver定义了两个方法给子类继承,用于通知更改
public abstract class DataSetObserver {
    public void onChanged() {}
    public void onInvalidated() {}
}
  1. 然后AdapterDataSetObserver继承了这两个方法,在onChanged的时候申请了重绘视图
class AdapterDataSetObserver extends DataSetObserver {
    @Override
    public void onChanged() {
   		...
		requestLayout(); //这个是向系统申请重新绘制视图的方法
	}
}
  1. Listview 继承 AbsListView,我们在给它设置setAdapter的时候,创建了AdapterDataSetObserver

@Override
public void setAdapter(ListAdapter adapter) {
	...
      mDataSetObserver = new AdapterDataSetObserver();
      mAdapter.registerDataSetObserver(mDataSetObserver);
	...
}

同时,把这个AdapterDataSetObserver注册到了mAdapter里。

  1. 另一边,抽象类Observable<T>维护了一个ArrayList,用来存放观察者
public abstract class Observable<T> {
	protected final ArrayList<T> mObservers = new ArrayList<T>();
	public void registerObserver(T observer) {...}
	public void unregisterObserver(T observer) {...}
}
  1. DataSetObservable继承 Observable<DataSetObserver>并指定了泛型类型为前面的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();
        }
    }
}
  1. 在ArrayAdapter的父类BaseAdapter中创建了DataSetObservable;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
    private final DataSetObservable mDataSetObservable = new DataSetObservable();
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }
    public void notifyDataSetInvalidated() {
        mDataSetObservable.notifyInvalidated();
    }

这样一来,ArrayAdapter 其实默认就拥有了四个方法,

registerDataSetObserver
unregisterDataSetObserver
notifyDataSetChanged
notifyDataSetInvalidated

现在都准备好了,
当我们创建Listview后,就给它设置adapter,这时,adapter顺便把Listview里的AdapterDataSetObserver注册到了ArrayList<T> mObservers观察者列表里。
当我们更新Listview列表数据时,就要调用adapternotifyDataSetChanged,这样就会去遍历所有ArrayList<T> mObservers集合里的观察者,并调用他们的onChanged,此时,Listview里的AdapterDataSetObserver就会调用onChanged,从而申请Listview重新绘制。这样Listview就会刷新显示了。


代码看完了,现在假如我们自己要写个观察者模式怎么做?

1.新建抽象观察者,只写抽象方法,用来接收信号

public abstract class 抽象观察者{
	public void 接收信号{};
}

2.新建具体观察者,重载方法,用来做具体收到信号后干什么

public class 实际观察者 extends 抽象观察者{
	@Override
	public void 接收信号{
		宣告世界,我收到信号了.
	}
}

3.新建抽象被观察者,保存一个List集合,用来存储所有观察者。

public abstract class 抽象被观察者<T> {
	protected final ArrayList<T> mObservers = new ArrayList<T>();
	public void 添加到集合(T observer) {...}
	public void 从集合删除(T observer) {...}
}

4.新建具体被观察者,用来更新数据,通知他人。

public class 具体被观察者<泛型指定抽象观察者> {
public void 通知所有人() {
   synchronized(mObservers) {
       for (int i = mObservers.size() - 1; i >= 0; i--) {
           mObservers.get(i).接收信号();
       }
   }
}

5.基本四个类已经写好了,剩下的就是注册和使用了。
先写服务端,用来注册和通知。

public class 服务端{
	//新建一个具体被观察者
	new 具体被观察者
	//提供方法用来把观察者添加和删除被观察者的集合里
	public void 添加观察者{
		具体观察者.添加到集合();
	}
	...
}

新建客户端,用来接收通知。

public class 客户端 {
	//新建一个观察者
	new 实际观察者 
	//获取
	设置服务端
	//调用服务端的添加删除方法,把这里的实际观察者放到服务端那边
	服务端.添加观察者

	//现在一切都设置好了。
	//当服务端有了新通知的时候
	具体的,比如网络那边有新消息发给你了
	这时候服务端就会调用具体的被观察者去发送通知
	然后客户端这里的观察者就会收到通知。
}
实际上总共就四个对象。
  • A想接收信号类
  • B想发送信号的类
  • C可以观察接收信号的类
  • D可以发送信号的类

然后ABCD都可以做抽象继承,这样就会有8个类了,简单点写就是4个类了。

操作过程:
  • 新建的时候,A里面新建C 持有B,B里面新建D ,A让B把C放到D的列表里
  • 更新的时候,B让D,向D的列表里所有的C发送信号,这时候A里面的C就会接收到信号
总结:

实际上就是搞清楚一下几点。

  1. 谁想接收信号 就新建一个观察者,添加到集合里
  2. 谁想发送信号 就新建一个被观察者,提供方法来添加和删除,以及通知消息
  3. 谁可以发出信号 就用一个集合来存储那些观察者,并提供方法遍历集合发送消息
  4. 谁可以接收信号 就用来接收消息,做你想做的事
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章