Android设计模式之观察者模式_第1页
Android设计模式之观察者模式_第2页
Android设计模式之观察者模式_第3页
Android设计模式之观察者模式_第4页
Android设计模式之观察者模式_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

1、 /* * 观察者模式 * 定义对象间的一种一个 (Subject) 对多 (Observer) 的依赖关系, 当一个对象的状态发 送改变时,所以依赖于它的 * 对象都得到通知并被自动更新 *当然,MVC只是Observer模式的一个实例。 Observer模式要解决的问题为: * 建立一个一( Subject )对多( Observer )的依赖关系,并且做到当“一”变化的时候, * 依赖这个 “一” 的多也能够同步改变。 最常见的一个例子就是: 析时候, * 我们希望能够提供多种形式的表示 (例如以表格进行统计显示、 统计显示等) 。 * 这些表示都依赖于同一组数据, 我们当然需要当数据改

2、变的时候, 够同时改变。 * Observer 模式就是解决了这一个问题。 对同一组数据进行统计分 柱状图统计显示、 百分比 所有的统计的显示都能 * 适用性: *1. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面 *将这两者封装成独立的对象中以使它们可以各自独立的改变和服用 2. 当对一个对象的改变需要同时改变其他对象, 而不知道具体有多少对象有待改变 3. 当一个对象必须通知其它对象,而它又不能假定其它对象是谁 * 参与者: *1. Subject (目标) *目标知道它的观察者,可以有任意多个观察者观察同一个目标 *提供注册和删除观察者对象的接口 2. Observer (观察者

3、) 为那些在目标发生改变时需获得通知的对象定义个更新的接口 3. ConcreteSubject (具体目标) 将有关状态存入各 ConcreteObserver 对象 当它的状态发送改变时,向它的各个观察者发出通知 4. ConcreteObserver (具体观察者) 维护一个指向 ConcreteObserver 对象的引用 存储有关状态,这些状态应与目标的状态保持一致 实现 Observer 的更新接口是自身状态与目标的状态保持一致 * */ 有空我将把UML图补上。 下面看看 Android 使用到的观察者模式 . 观察者(DataSetObserver ),目标(Observabl

4、eT),具体目标(DataSetObserverable ) Observer( 观察者 ) , DataSetObserver 抽象 2 个方法,一个是观察数据改变的方法,一个是 观察数据变成无效(或者不可用)时的方法。 源码路径: framework/base/core/java/android/database/DataSetObserver.java package android.database; /* The typically added to a * Receives call backs when a data set has been changed, or madein

5、valid. data sets * that are observed are link Cursors or link android.widget.Adapters. * DataSetObserver must be implemented by objects which are DataSetObservable. */ public abstract class DataSetObserver /* * This method is called when the entire data set has changed, * most likely through a call

6、to link Cursor#requery() on a link Cursor. */ public void onChanged() / Do nothing /* * This method is called when the entire data becomes invalid, or link 撤销 * most likely through a call to link Cursor#deactivate() Cursor#close() on a * link Cursor. */ public void onInvalidated() / Do nothing Subje

7、ct( 目标 ) , ObservableT 是一个泛型的抽象类,主要功能是注册和 observer 。 源码路径: framework/base/core/java/android/database/Observable.java package android.database; import java.util.ArrayList; /* * Provides methods for (un)registering arbitrary observers in an ArrayList. */ public abstract class ObservableT /* * The list

8、 of observers. An observer can be in the list at most * once and will never be null. */ protected final ArrayListT mObservers = new ArrayListT(); /* * Adds an observer to the list. The observer cannot be null and it must not already * be registered. * param observer the observer to register * throws

9、 IllegalArgumentException the observer is null * throws IllegalStateException the observer is already registered */ public void registerObserver(T observer) if (observer = null) observer is null.); thrownew IllegalArgumentException(The synchronized(mObservers) if (mObservers.contains(observer) + obs

10、erver + throw new IllegalStateException(Observer is already registered.); mObservers.add(observer); /* * Removes a previously registered observer. The observer must not be null and it * must already have been registered. * param observer the observer to unregister * throws IllegalArgumentException t

11、he observer is null * throws IllegalStateException the observer is not yet registered */ public void unregisterObserver(T observer) if (observer = null) observer is null.); thrownew IllegalArgumentException(The synchronized(mObservers) int index = mObservers.indexOf(observer); if (index = -1) + obse

12、rver + throw new IllegalStateException(Observer was not registered.); mObservers.remove(index); /* * Remove all registered observer */ public void unregisterAll() synchronized(mObservers) mObservers.clear(); ConcreateSubject( 具 体 目 标 ) , 实 现 的 方 法 同 Oberver 一 样 , 只 不 过 它 是 通 知 ArrayListObserver 下的每个

13、 Oberver 去执行各自的 action 。 源码路径: framework/base/core/java/android/database/DataSetObservable.java package android.database; /* * A specialization of Observable for DataSetObserver that provides methods for * invoking the various callback methods of DataSetObserver. */ public class DataSetObservable ex

14、tends ObservableDataSetObserver /* * 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) / since onChanged() is implemented by the app, it could do a

15、nything, including removing itself from link mObservers - and that could cause / problems if / an iterator is used on the ArrayList link mObservers. / to avoid such problems, just march thru the list in the reverse order. for (int i = mObservers.size() - 1; i = 0; i-) mObservers.get(i).onChanged();

16、/* * 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 (int i = mObservers.size() - 1; i = 0; i-) mObservers.get(i).onInvalidated(); ConcreateObserver( 具体观察者

17、 ), 具体观察者的任务是实实在在执行 action 的类,一般由开 发者根据实际情况,自己实现。 android 也有实现的例子 源码路径: framework/base/core/java/android/widget/AbsListView.java extends class AdapterDataSetObserver AdapterViewListAdapter.AdapterDataSetObserver Override public void onChanged() super.onChanged(); if (mFastScroller != null) mFastScro

18、ller.onSectionsChanged(); Override public void onInvalidated() super.onInvalidated(); if (mFastScroller != null) mFastScroller.onSectionsChanged(); framework/base/core/java/android/widget/AdapterView.java class AdapterDataSetObse( 参 考 : http:/)rver DataSetObserver private Parcelable mInstanceState =

19、 null; Override public void onChanged() mDataChanged = true; mOldItemCount = mItemCount; mItemCount = getAdapter().getCount(); if (DBG) Xlog.d(TAG, AdapterView onChanged: mOldItemCount = + mOldItemCount ,mItemCount ,getAdapter() = + getAdapter() + ,AdapterView Throwable(onChanged); + mItemCount + +

20、AdapterView.this, new / 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

21、 = null; else rememberSyncState(); checkFocus(); requestLayout(); extends Override public void onInvalidated() mDataChanged = true; if (DBG) Xlog.d(TAG, + mOldItemCount AdapterView onInvalidated: mOldItemCount = + mItemCount + + AdapterView.this, new ,mItemCount ,getAdapter() = + getAdapter() + ,Ada

22、pterView Throwable(onInvalidated); if (AdapterView.this.getAdapter().hasStableIds() / Rememberthe current state for the case where our hosting activity is being / stopped and later restarted mInstanceState = AdapterView.this.onSaveInstanceState(); / Data is invalid so we should reset our state mOldI

23、temCount = mItemCount; mItemCount = 0; mSelectedPosition = INVALID_POSITION; mSelectedRowId = INVALID_ROW_ID; mNextSelectedPosition = INVALID_POSITION; mNextSelectedRowId = INVALID_ROW_ID; mNeedSync = false; checkFocus(); requestLayout(); public void clearSavedState() mInstanceState = null; 型运用是大家熟悉

24、的 BaseAdapter ,BaseAdapter 关联了一个 DataSetObservable 对象, 并实 现 registerDataSetObserver 和 unregisterDataSetObserver 两个方法实现注册和撤销 Observer ,方法 notifyDataSetChanged 间接调用 Observer 的实现者的 onChange() 方法, 以 item 实例: 达到通知数据改变的作用。使用 ListView 和 BaseAdapter 组合时,当 BaseAdapter 的 改变时,我们经常会调用 notifyDataSetChanged() ,通知

25、 Listview 刷新。 的 如何 但 是 , 但 是 , 但 是 , 我 们 从 来 没 有 调 用 BaseAdapter registerDataSetObserver(DataSetObserver observer) 注册 Observer ,那么 Listview 接收到通知,并执行刷新动作呢? 我们来看看 ListView 做了什么 /* * Sets the data behind this ListView. * The adapter passed to this method may be wrapped by a link WrapperListAdapter, *

26、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. *

27、 see #getAdapter() */ Override public void setAdapter(ListAdapter adapter) if (mAdapter != null mDataSetObserver != null) mAdapter.unregisterDataSetObserver(mDataSetObserver); resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() 0| mFooterViewInfos.size() 0) mAdapter = new HeaderViewListAdapt

28、er(mHeaderViewInfos, mFooterViewInfos, adapter); else mAdapter = adapter; mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; / AbsListView#setAdapter will update choice mode states. super.setAdapter(adapter); if (mAdapter != null) mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); chec

温馨提示

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

评论

0/150

提交评论