当前位置: 代码迷 >> Android >> Android学习之Adapter(适配器)源代码分析与观察者模式的施用(一)
  详细解决方案

Android学习之Adapter(适配器)源代码分析与观察者模式的施用(一)

热度:319   发布时间:2016-05-01 12:54:06.0
Android学习之Adapter(适配器)源代码分析与观察者模式的运用(一)

         博客地址:http://blog.csdn.net/jiangqq781931404    

          有兴趣一起交流学习,欢迎联系.

  

        之前已经学习过了观察者模式(点击进入观察者模式文章),今天来结合一下android的frameworks中的Adapter等相关类来更加深入的学习一下观察者模式的具体使用;

     在安卓App开发中,我们会经常使用到一些适配器来进行数据绑定例如:SimpleAdapter,ArrayAdapter,BaseAdapter..等等的适配器,那就看下一张图片,是各种Adapter(适配器)的类的继承实现图:

     

 

     上面我们可以清晰看出Adapter就是适配器中的父类,也是一个接口,这个接口有两个接口实现分别是ListAdapter与SpinnerAdapter,然后就是一些实现类与接口;

      那平时我们要经常在数据绑定的时候,要使用到适配器,就先看父类的吧

     

      一:Adapter 在源代码中的路径:frameworks\base\core\java\android\widget\Adapter.java

 

public interface Adapter {    /**     * Register an observer that is called when changes happen to the data used by this adapter.     *     * @param observer the object that gets notified when the data set changes.     */    void registerDataSetObserver(DataSetObserver observer);    /**     * Unregister an observer that has previously been registered with this     * adapter via [email protected] #registerDataSetObserver}.     *     * @param observer the object to unregister.     */    void unregisterDataSetObserver(DataSetObserver observer);    int getCount();           Object getItem(int position);        long getItemId(int position);        boolean hasStableIds();        View getView(int position, View convertView, ViewGroup parent);    static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE;        int getViewTypeCount();        static final int NO_SELECTION = Integer.MIN_VALUE;     boolean isEmpty();}

       这个类有一些最基本的方法,其中有个两个这样的方法void registerDataSetObserver(DataSetObserver observer)与void unregisterDataSetObserver(DataSetObserver observer);这是主题角色进行添加于删除观察者角色的,此时的Adapte类就相当于抽象主题角色;

 

          [注]在观察者模式中有如下几种角色:

         ①: 创建一个Subject接口,里面有三个方法分别是addObserver,removeObserver,notifyObserver,

            创建一个Observer接口,里面有个更新自己的方法update();

        ②: 创建ConcreteSubject实现Subject接口,相应实现里面的方法,把观察者对象注册进来;当时主题角色发生状态改变的时候,去调用notifyObserver()方法来给已经注册的观察者进行通知,然后观察者来自己更新自己.

        ③:创建ConcreterObserver实现Observer接口,当观察者接受到主题角色发的通知,自己调用update()更新自己.

    

     那么根据上面的Adapter的抽象主题角色已经有了,那么什么才是具体主题角色呢?别急,我们这里可以这样分析一下,具体主题角色肯定是要实现抽象主题角色中的注册于解除观察者的方法,那么现在来看上面那张类的继承图,发现下面有ListAdapter与SpinnerAdapter类,这两个是接口,暂时略过,在看其他的实现类,这里我用BaseAdapter类进行分析

 

       一:BaseAdapter 在源代码中的路径:frameworks\base\core\java\android\widget\BaseAdapter.java

      BaseAdapter就是一个具体主题角色了,看下如下的实现注册观察者与接触观察者的源代码:

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {    private final DataSetObservable mDataSetObservable = new DataSetObservable();    public boolean hasStableIds() {        return false;    }        public void registerDataSetObserver(DataSetObserver observer) {        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();    }        public void notifyDataSetInvalidated() {        mDataSetObservable.notifyInvalidated();    }    public boolean areAllItemsEnabled() {        return true;    }    public boolean isEnabled(int position) {        return true;    }    public View getDropDownView(int position, View convertView, ViewGroup parent) {        return getView(position, convertView, parent);    }    public int getItemViewType(int position) {        return 0;    }    public int getViewTypeCount() {        return 1;    }        public boolean isEmpty() {        return getCount() == 0;    }}

看上面的源代码:

public void registerDataSetObserver(DataSetObserver observer) {        mDataSetObservable.registerObserver(observer);    }   

public void unregisterDataSetObserver(DataSetObserver observer) {        mDataSetObservable.unregisterObserver(observer);    }

还是很清晰的,这样一分析,那么源代码中

private final DataSetObservable mDataSetObservable = new DataSetObservable();mDataSetObservable该实例就是一个具体观察者的角色了,该类是DataSetObservable继承于 Observable<DataSetObserver>的,Observable是一个带泛型的抽象类,其中已经实现了观察者的的注册于解除(具体代码的路为:frameworks\base\core\java\android\database\Observable.java),

  

   我们重要的看一下这个具体观察者角色DataSetObservable(路径为:frameworks\base\core\java\android\database\DataSetObservable.java)其中实现数据源变化通知观察者后,观察者进行一个个更新的数据,代码如下:

public class DataSetObservable extends Observable<DataSetObserver> {    /**     * 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) {                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();            }        }    }

    

      这样使用注册观察者和数据更新的时候把简要流程讲一下:首先我们需要注册观察者调用registerDataSetObserver(DataSetObserver),然后调用抽象类Observable中的registerObserver(T observer)方法,进行观察者的注册;当我们需要绑定的数据源发生变化的时候,具体主题角色DataSetObservable回去调用notifyChanged()方法来通知所有的观察者,让各个观察者来自己的更新的方法,来进行更新数据;

     最后还是要说一下一个抽象类Observable.java(路径:frameworks\base\core\java\android\database\Observable.java)    还是贴一下代码,其中有详细的观察者的注册于解除的方法:

public abstract class Observable<T> {    /**     * The list of observers.  An observer can be in the list at most     * once and will never be null.     */    protected final ArrayList<T> mObservers = new ArrayList<T>();    /**     * 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 IllegalArgumentException the observer is null     * @throws IllegalStateException the observer is already registered     */    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);        }    }    /**     * 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 the observer is null     * @throws IllegalStateException the observer is not yet registered     */    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);        }    }        /**     * Remove all registered observer     */    public void unregisterAll() {        synchronized(mObservers) {            mObservers.clear();        }            }

    

       好了今天就暂时学习到这里吧,相信这样一跟踪一下源代码,相信会对观察者模式会有一个更深一点的认识吧,同时也希望能够在实际情况中运用好观察者模式;


 

    

1楼leisure4861前天 18:28
沙发呀。。。
  相关解决方案