观察者模式与监听器机制.doc_第1页
观察者模式与监听器机制.doc_第2页
观察者模式与监听器机制.doc_第3页
观察者模式与监听器机制.doc_第4页
观察者模式与监听器机制.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 观察者模式与监听器机制1.1 观察者模式The observer pattern (a subset of the publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.l The Java Swing library makes extensive use of the observer pattern for event managementl The Java Servlet API is heavily using observer pattern to notify application entities about significant events, observed by web container. Listeners are provided for servlet and session lifecycle, session migration, changes to scoped attributes etc.l PerfectJPattern Open Source Project, Provides a context-free and type-safe implementation of the Observer Pattern in Java.1.2 监听器(Listener)机制代码的基本框架:* 被监控着package com.wonders.group;import java.util.Collection;public class ModelTie private Collection dataSet;public interface DataSetSupervioer public void onChange();private DataSetSupervioer dataSetChangeListener;public void setDataSetChangeListener(DataSetSupervioer dataSetChangeListener) this.dataSetChangeListener = dataSetChangeListener;public void notifyDataSetChange() if (null != dataSetChangeListener) dataSetChangeListener.onChange();public Collection getDataSet() return dataSet;public ModelTie setDataSet(Collection dataSet) this.dataSet = dataSet;this.notifyDataSetChange(); / 数据设置完毕要通知监听器进行更新操作return this;* 监控者package com.wonders.group;import java.util.Collection;import java.util.Iterator;import com.wonders.group.ModelTie.DataSetSupervioer;public class PresentationTie private ModelTie model;public PresentationTie() super();/ 添加监听器model.setDataSetChangeListener(new DataSetSupervioer() public void onChange() / 填写一些前置操作,如更新数据DisplayModel(); / 重新绘制/ 填写一些后置操作,如更新状态);public void DisplayModel() Collection collection = model.getDataSet();if (collection != null) for (Iterator iterator = collection.iterator(); iterator.hasNext();) System.out.println(Object) iterator.next().toString();/ 其他等等操作public ModelTie getModel() return model;public void setModel(ModelTie model) this.model = model;2、 ArrayAdapter的观察者实现机制以下仅罗列关键代码:public class ArrayAdapter extends BaseAdapter implements Filterable private boolean mNotifyOnChange = true; /* * Adds the specified object at the end of the array. */ public void add(T object) if (mOriginalValues != null) synchronized (mLock) mOriginalValues.add(object); if (mNotifyOnChange) notifyDataSetChanged(); else mObjects.add(object); if (mNotifyOnChange) notifyDataSetChanged(); /* * Inserts the specified object at the specified index in the array. */ public void insert(T object, int index) if (mOriginalValues != null) synchronized (mLock) mOriginalValues.add(index, object); if (mNotifyOnChange) notifyDataSetChanged(); else mObjects.add(index, object); if (mNotifyOnChange) notifyDataSetChanged(); /* * Removes the specified object from the array. */ public void remove(T object) if (mOriginalValues != null) synchronized (mLock) mOriginalValues.remove(object); else mObjects.remove(object); if (mNotifyOnChange) notifyDataSetChanged(); /* * Remove all elements from the list. */ public void clear() if (mOriginalValues != null) synchronized (mLock) mOriginalValues.clear(); else mObjects.clear(); if (mNotifyOnChange) notifyDataSetChanged(); /* * Sorts the content of this adapter using the specified comparator. */ public void sort(Comparator comparator) Collections.sort(mObjects, comparator); if (mNotifyOnChange) notifyDataSetChanged(); Override public void notifyDataSetChanged() super.notifyDataSetChanged(); / 关键代码,这个notifyDataSetChanged()是从父类BaseAdapter继承过来的,所以看看在父类中它干了些什么 mNotifyOnChange = true;/* * Common base class of common implementation for an link Adapter that can be * used in both link ListView (by implementing the specialized * link ListAdapter interface and link Spinner (by implementing the * specialized link SpinnerAdapter interface. */public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter private final DataSetObservable mDataSetObservable = new DataSetObservable(); public void registerDataSetObserver(DataSetObserver observer) 这对方法用来注册或注销观察ArrayAdapter的观察者的 mDataSetObservable.registerObserver(observer); public void unregisterDataSetObserver(DataSetObserver observer) mDataSetObservable.unregisterObserver(observer); /* * Notifies the attached View that the underlying data has been changed * and it should refresh itself. */ public void notifyDataSetChanged() mDataSetObservable.notifyChanged(); / 关键代码:说明调的是成员变量mDataSetObservable的方法,所以进入DataSetObservable看看具体是如何操作的 public void notifyDataSetInvalidated() mDataSetObservable.notifyInvalidated(); package android.database;/* * A specialization of Observable for DataSetObserver that provides methods for * invoking the various callback methods of DataSetObserver. */public class DataSetObservable extends Observable /* * Invokes onChanged on each observer. Called when the data set being observed has * changed, and which when read contains the new state of the data. */ public void notifyChanged() synchronized(mObservers) for (DataSetObserver observer : mObservers) / 这里的mObservers是哪来的呢?继续追踪,但首先可以判断是来自Observable的。进入看看 observer.onChanged(); /* * Invokes onInvalidated on each observer. Called when the data set being monitored * has changed such that it is no longer valid. */ public void notifyInvalidated() synchronized (mObservers) for (DataSetObserver observer : mObservers) observer.onInvalidated(); public abstract class Observable /* * The list of observers. An observer can be in the list at most * once and will never be null. */ protected final ArrayList mObservers = new ArrayList(); 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(); 对于DataSetObserver基类,我们也给出代码:public abstract class DataSetObserver public void onChanged() public void onInvalidated() 综合起来分析就是,ArrayAdapter使自己具备被观察的能力的方法是,ArrayAdapter内部有一个private final DataSetObservable mDataSetObservable = new DataSetObservable()的变量,这个变量一方面维护着一个保存观察者的数据结构,另一方面提供registerDataSetObserver(DataSetObserver observer)和unregisterDataSetObserver(DataSetObserver observer)来管理观察自己的对象;而当ArrayAdapter绑定数的据发生变化时,它会调用内部的notifyDataSetChanged()方法,但这个方法最终是调用mDataSetObservable的notifyChanged()方法。在该方法里,该方法会逐一审视有哪些观察者在观察我,然后调用观察者的观察方法onChanged()。3、 ListView观察ArrayAdapter的数据集的机制通过以上分析可以知道,ListView要实现观察ArrayAdapter,需要将自己注册到ArrayAdapter的DataSetObservable mDataSetObservable里去,注册的方法是调用ArrayAdapter的registerDataSetObserver(DataSetObserver observer)方法。那ListView是如何将自己注册上去的呢?具体过程如下:public class ListView extends AbsListView /* * Sets the data behind this ListView. * * The adapter passed to this method may be wrapped by a link WrapperListAdapter, * depending on the ListView features currently in use. For instance, adding * headers and/or footers will cause the adapter to be wrapped. * * param adapter The ListAdapter which is responsible for maintaining the * data backing this list and for producing a view to represent an * item in that data set. */ Override public void setAdapter(ListAdapter adapter) if (null != mAdapter) mAdapter.unregisterDataSetObserver(mDataSetObserver); / 关键的成员变量,继承自AbsListView,等下去看看AbsListView关于mDataSetObserver的内容 resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() 0| mFooterViewInfos.size() 0) mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); else mAdapter = adapter; mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; if (mAdapter != null) mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); checkFocus(); mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); / 在这里进行注册,注册为数据集的观察员 mRecycler.setViewTypeCount(mAdapter.getViewTypeCount(); int position; if (mStackFromBottom) position = lookForSelectablePosition(mItemCount - 1, false); else position = lookForSelectablePosition(0, true); setSelectedPositionInt(position); setNextSelectedPositionInt(position); if (mItemCount = 0) / Nothing selected checkSelectionChanged(); if (mChoiceMode != CHOICE_MODE_NONE & mAdapter.hasStableIds() & mCheckedIdStates = null) mCheckedIdStates = new LongSparseArray(); else mAreAllItemsSelectable = true; checkFocus(); / Nothing selected checkSelectionChanged(); if (mCheckStates != null) mCheckStates.clear(); if (mCheckedIdStates != null) mCheckedIdStates.clear(); requestLayout();public abstract class AbsListView extends AdapterView implements TextWatcher, ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener, ViewTreeObserver.OnTouchModeChangeListener /* * Should be used by subclasses to listen to changes in the dataset */ AdapterDataSetObserver mDataSetObserver;/ mDataSetObserver就是在这里定义的。那我们再看看AdapterDataSetObserver是什么类型的数据,看看当数据发生变化的时候,该类会进行什么样的动作。 /* * The adapter containing the data to be displayed by this view */ListAdapter mAdapter;值得注意的是,AdapterDataSetObserver是AdapterView里的一个内部类(/1.1_r1_src/android/widget/class-use/AdapterView.AdapterDataSetObserver.html ),具体我们查看下代码:class AdapterDataSetObserver extends DataSetObserver private Parcelable mInstanceState = null; Override public void onChanged() mDataChanged = true; mOldItemCount = mItemCount; mItemCount = getAdapter().getCount(); / Detect the case where a cursor that was previously invalidated has / been repopulated with new data. if (AdapterView.this.getAdapter().hasStableIds() & mInstanceState != null & mOldItemCount = 0 & mItemCount 0) AdapterView.this.onRestoreInstanceState(mInstanceState); mInstanceState = null; else rememberSyncState(); checkFo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论