观察者模式与监听器机制.doc

上传人:asd****56 文档编号:69685789 上传时间:2023-01-07 格式:DOC 页数:8 大小:148.50KB
返回 下载 相关 举报
观察者模式与监听器机制.doc_第1页
第1页 / 共8页
观察者模式与监听器机制.doc_第2页
第2页 / 共8页
点击查看更多>>
资源描述

《观察者模式与监听器机制.doc》由会员分享,可在线阅读,更多相关《观察者模式与监听器机制.doc(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、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 met

2、hods. 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

3、. 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;impor

4、t 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 = dataSetChangeLi

5、stener;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 co

6、m.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() / 填写一些前置

7、操作,如更新数据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()

8、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 (m

9、OriginalValues != 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 in

10、dex) 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

11、(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 mOb

12、jects.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

13、() 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 li

14、nk 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) 这对方法用来注册

15、或注销观察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 v

16、oid notifyDataSetChanged() mDataSetObservable.notifyChanged(); / 关键代码:说明调的是成员变量mDataSetObservable的方法,所以进入DataSetObservable看看具体是如何操作的 public void notifyDataSetInvalidated() mDataSetObservable.notifyInvalidated(); package android.database;/* * A specialization of Observable for DataSetObserver that pr

17、ovides 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 no

18、tifyChanged() 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

19、 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 A

20、rrayList(); 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); pub

21、lic 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(ind

22、ex); public void unregisterAll() synchronized(mObservers) mObservers.clear(); 对于DataSetObserver基类,我们也给出代码:public abstract class DataSetObserver public void onChanged() public void onInvalidated() 综合起来分析就是,ArrayAdapter使自己具备被观察的能力的方法是,ArrayAdapter内部有一个private final DataSetObservable mDataSetObservable

23、 = new DataSetObservable()的变量,这个变量一方面维护着一个保存观察者的数据结构,另一方面提供registerDataSetObserver(DataSetObserver observer)和unregisterDataSetObserver(DataSetObserver observer)来管理观察自己的对象;而当ArrayAdapter绑定数的据发生变化时,它会调用内部的notifyDataSetChanged()方法,但这个方法最终是调用mDataSetObservable的notifyChanged()方法。在该方法里,该方法会逐一审视有哪些观察者在观察我,

24、然后调用观察者的观察方法onChanged()。3、 ListView观察ArrayAdapter的数据集的机制通过以上分析可以知道,ListView要实现观察ArrayAdapter,需要将自己注册到ArrayAdapter的DataSetObservable mDataSetObservable里去,注册的方法是调用ArrayAdapter的registerDataSetObserver(DataSetObserver observer)方法。那ListView是如何将自己注册上去的呢?具体过程如下:public class ListView extends AbsListView /*

25、* 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

26、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关

27、于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 (

28、mAdapter != null) mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); checkFocus(); mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); / 在这里进行注册,注册为数据集的观察员 mRecycler.setViewTypeCount(m

29、Adapter.getViewTypeCount(); int position; if (mStackFromBottom) position = lookForSelectablePosition(mItemCount - 1, false); else position = lookForSelectablePosition(0, true); setSelectedPositionInt(position); setNextSelectedPositionInt(position); if (mItemCount = 0) / Nothing selected checkSelecti

30、onChanged(); 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 (mCheckedId

31、States != 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

32、 the dataset */ AdapterDataSetObserver mDataSetObserver;/ mDataSetObserver就是在这里定义的。那我们再看看AdapterDataSetObserver是什么类型的数据,看看当数据发生变化的时候,该类会进行什么样的动作。 /* * The adapter containing the data to be displayed by this view */ListAdapter mAdapter;值得注意的是,AdapterDataSetObserver是AdapterView里的一个内部类( ),具体我们查看下代码:cla

33、ss 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

34、with new data. if (AdapterView.this.getAdapter().hasStableIds() & mInstanceState != null & mOldItemCount = 0 & mItemCount 0) AdapterView.this.onRestoreInstanceState(mInstanceState); mInstanceState = null; else rememberSyncState(); checkFocus(); requestLayout(); / 这里是关键:这就是为什么数据发生了变化,视图可以随之变换的原因,因为它会

35、调用框架,来进行重新绘制。最终调用的代码看紧接着的代码 Override public void onInvalidated() mDataChanged = true; if (AdapterView.this.getAdapter().hasStableIds() / Remember the current state for the case where our hosting activity is being / stopped and later restarted mInstanceState = AdapterView.this.onSaveInstanceState();

36、/ Data is invalid so we should reset our state mOldItemCount = mItemCount; mItemCount = 0; mSelectedPosition = INVALID_POSITION; mSelectedRowId = INVALID_ROW_ID; mNextSelectedPosition = INVALID_POSITION; mNextSelectedRowId = INVALID_ROW_ID; mNeedSync = false; checkSelectionChanged(); checkFocus(); r

37、equestLayout(); public void clearSavedState() mInstanceState = null; 最终调用的代码(from View.class) /* * Call this when something has changed which has invalidated the * layout of this view. This will schedule a layout pass of the view * tree. */ public void requestLayout() if (ViewDebug.TRACE_HIERARCHY) ViewDebug.trace(this, ViewDebug.HierarchyTraceType.REQUEST_LAYOUT); mPrivateFlags |= FORCE_LAYOUT; if (mParent != null & !mParent.isLayoutRequested() mParent.requestLayout();

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 财经金融

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁