论安卓适配器中的观察者模式

来源:互联网 发布:淘宝代发怎么发货 编辑:程序博客网 时间:2024/05/22 00:30

观察者模式

观察者模式也通常称为 发布/订阅模式,是一种常见的软件开发模式。


在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。


举个类似的栗子:

天气更新,气象局一般都有一个气象信息采集的部门,一个和外界合作的运营部门,气象信息采集部门负责数据的采集,和运营部门主动沟通。合作运营部门这是负责把最新的气象信息发给和气象局合作的电视台,网站等等。

运营部门充当的角色就是管理观察者的管理员

他们的主要任务就是添加新的合作单位,或者是终止某个单位或者所有单位的合作,还有当气象采集部门发送新的气象报告的时候需要把这些新的气象信息发给那些合作单位。

而和气象局合作的电视台,网站等等他们的角色就是观察者

他们需要在接受到最新的气象报告后,通知给其他群众,或者做一些其它的工作。

在这个过程中,运营部门和跟他们合作的电视台、网站直接就是一种订阅-发布的关系。

如果还是不明白推荐一篇详解的博客:

http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html


android 适配器中的观察者模式

还记得一次面试中,被问道,为什么存在适配器这个东西,而不是数据直接的绘制ui呢?当时只知道感觉这么做就是简单,就是好,可就是说不出个所以然来。其实适配器其实也是一种设计模式的产物,这种设计模式就被称为适配器模式。现在看来采用适配器模式能够很好的降低耦合,如果直接绘制就降低了拓展性,而且也就没有listview item回收复用节省内存。

如果需要详细了解适配器模式的话也推荐一篇很不错的帖子:

http://blog.csdn.net/zhangjg_blog/article/details/18735243

还记得基本是listview的用法么?

  1. 需要获取listview的实例
  2. 通过List数据集合构建listview需要的适配器adapter
  3. 将listview和适配器绑定

所以这里面的三个主要对象抽象来看就是数据、适配器、UI

详细分析

数据

这里写图片描述


适配器

这里写图片描述


UI

这里写图片描述


可能这几张图看上去有点吃力,那么结合图做下分析解释:

Observable< T >就是类似前面的那个运营部门,它是一个抽象类,它的作用就是管理观察者,包括添加,删除等等。下面是源码片段:

这里写图片描述



DataSetObserve则是一个Observable< T >的子类,它在继承父类的基础上添加了新的公共方法,源码片段如下:

这里写图片描述



DataSetObserver就类似前面的那个电视台,网站,它也是一个抽象类,他就是观察者,源码片段如下:

这里写图片描述



AdapterDataSetObserver是一个DataSetObserver在AdapterView里面的子类

781  class AdapterDataSetObserver extends DataSetObserver {782 783         private Parcelable mInstanceState = null;784 785         @Override786         public void onChanged() {787             mDataChanged = true;788             mOldItemCount = mItemCount;789             mItemCount = getAdapter().getCount();790 791             // Detect the case where a cursor that was previously invalidated has792             // been repopulated with new data.793             if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null794                     && mOldItemCount == 0 && mItemCount > 0) {795                 AdapterView.this.onRestoreInstanceState(mInstanceState);796                 mInstanceState = null;797             } else {798                 rememberSyncState();799             }//刷新UI800             checkFocus();801             requestLayout();    802         }803 804         @Override805         public void onInvalidated() {806             mDataChanged = true;807 808             if (AdapterView.this.getAdapter().hasStableIds()) {809                 // Remember the current state for the case where our hosting activity is being810                 // stopped and later restarted811                 mInstanceState = AdapterView.this.onSaveInstanceState();812             }813 814             // Data is invalid so we should reset our state815             mOldItemCount = mItemCount;816             mItemCount = 0;817             mSelectedPosition = INVALID_POSITION;818             mSelectedRowId = INVALID_ROW_ID;819             mNextSelectedPosition = INVALID_POSITION;820             mNextSelectedRowId = INVALID_ROW_ID;821             mNeedSync = false;822             //刷新UI823             checkFocus();824             requestLayout();825         }826 827         public void clearSavedState() {828             mInstanceState = null;829         }830     }

总结

整个过程中,UI是最关心数据变化的,因为数据变化,UI也就要跟着刷新。因此UI就派了观察者(T observer)去查看数据变化,这个派过去的观察者被适配器的观察者管理员(Observe(T))管理分配调用,当适配器收到数据更新的消息适配器观察者管理员逐个的通知观察者数据发生改变,要他们去通知自己的UI更新。

也就是在当我们调用ListView中的SetAdapter时,会将一个mDataSetObeserver(AdapterDataSetObserver 类)的观察者对象实例化,然后绑定在BaseAdapter的观察者管理员mDataSetObeserve(DataSetObserve类)中。

当我们数据改变的时候,我们一般要调用了BaseAdapter的notifyXXX(如:notifydatasetchanged)的方法,其实实际上这个方法也就是通过观察者管理员mDataSetObeserve发送这个notify通知给每一个观察者(即调用了DataSetObeserve的notifyXXX)。

最后ui派去的观察者收到了数据更新,接着就刷新页面(AdapterDataSetObserver 类中的onXXX 如:onChanged)。


他们之间的关系我用一个window画图工具花了张图

这里写图片描述

0 0
原创粉丝点击