• Android源码与设计模式之notifyDataSetChanged()方法与观察者模式


    BaseAdapter在调用notifyDataSetChanged()方法后,GridView就刷新了,下面从源码角度对此原理进行剖析。

    首先进到BaseAdapter中查看其notifyDataSetChanged()方法,发现它调用了DataSetObservable的notifyChanged()方法

    public abstract class BaseAdapter{
    private final DataSetObservable mDataSetObservable = new DataSetObservable();
    
    public void registerDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.registerObserver(observer);
        }
    
        public void unregisterDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.unregisterObserver(observer);
        }
    ...
        public void notifyDataSetChanged() {
            mDataSetObservable.notifyChanged();
        }
    ...
    }

    接着查看DataSetObservable的notifyChanged()方法,发现它调用了mObservers.get(i)的onChanged()方法,即DataSetObserver的onChanged()方法。

    public class DataSetObservable extends Observable<DataSetObserver> {
    ...
        public void notifyChanged() {
            synchronized(mObservers) {
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onChanged();
                }
            }
        }
    ... }

    其中的mObservers是在这里赋值的。

    public abstract class Observable<T> {
       
        protected final ArrayList<T> mObservers = new ArrayList<T>();
         
        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);
            }
        }
    }

    接下来寻找registerObserver()方法是在哪里调用的,发现刚才的BaseAdapter的registerDataSetObserver()方法调用了它。

    而此方法是在GridView的setAdapter方法中被调用的。

    ...class GridView ...{
    ...
    @Override
        public void setAdapter(ListAdapter adapter) {
            ...
    
            resetList();
            mRecycler.clear();        
            mAdapter = adapter;
    
        ...
    if (mAdapter != null) { ... mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); ... } else { checkFocus(); // Nothing selected checkSelectionChanged(); } requestLayout(); } ... }

    传进去的是AdapterDataSetObserver这个类,具体的刷新动作就是在这个类的onChanged()方法中完成的。

    class AdapterDataSetObserver extends DataSetObserver
     2   {
     3     private Parcelable mInstanceState = null;
     4 
     5     AdapterDataSetObserver() {
     6     }
     7     public void onChanged() { mDataChanged = true;
     8       mOldItemCount = mItemCount;
     9       mItemCount = getAdapter().getCount();
    10 
    11       if ((getAdapter().hasStableIds()) && (mInstanceState != null) && (mOldItemCount == 0) && (mItemCount > 0))
    12       {
    13         onRestoreInstanceState(mInstanceState);
    14         mInstanceState = null;
    15       } else {
    16         rememberSyncState();
    17       }
    18       checkFocus();
    19       requestLayout();
    20     }
    21     //...省略不必要代码
    22 }

    它会调用requestLayout()方法,又去调用scheduleTraversals()方法,这是刷新view的一个相关方法,具体实现本文暂不分析。

    1     public void requestLayout() {
    2         checkThread();
    3         mLayoutRequested = true;
    4         scheduleTraversals();
    5     }

    到此可以看到notifyDataSetChanged是怎么一步步实现的了。

    可以看到这个流程充分利用了观察者模式来激发view刷新。

    view.setAdapter(adapter)传入的adapter就是被观察者,而观察者是GridView父类AbsListView的成员变量mDataSetObserver。所以刷新的界面被选定为此gridview。

    这里的Observer相关的类都是由android实现的,但是与java实现思路相同。

  • 相关阅读:
    (转)A*算法详解及习题
    BZOJ1444[Jsoi2009]有趣的游戏——AC自动机+概率DP+矩阵乘法
    交通——set+dsu on tree
    [Codeforces1132G]Greedy Subsequences——线段树+单调栈
    BZOJ4482[Jsoi2015]套娃——贪心+set
    BZOJ4477[Jsoi2015]字符串树——可持久化trie树
    BZOJ4475[Jsoi2015]子集选取——递推(结论题)
    [UOJ86]mx的组合数——NTT+数位DP+原根与指标+卢卡斯定理
    BZOJ2428[HAOI2006]均分数据——模拟退火
    BZOJ4712洪水——动态DP+树链剖分+线段树
  • 原文地址:https://www.cnblogs.com/BlogCommunicator/p/6868635.html
Copyright © 2020-2023  润新知