观察者模式

2017-10-15  本文已影响12人  刘尔泽

引言

act 中有两个fragment,子fragment之间的通信,就会用到 观察者模式。
两个 activity 之间维护同一个数据源,如果要做到数据同步,就要用到观察者模式。

ListView 的数据跟新就会用到 观察者模式

概念

定义对象之间的一对多的依赖关系

每当一个对象状态发生改变时,其相关依赖对象皆得到通知,并被自动更新

使用场景

分析

被观察者,保存了 所有观察者引用的一个集合。
同时提供一个接口给我,用于增加删除 观察着对象

观察者收到通知,做自己的事情。
notify

Code

将观察者的引用集合 遍历执行 接口方法

调用JAVA 内置的接口 Observer

Observable 被观察者
Observe 观察者
主要是
this.setChanged();
this.notifyObservers(); 通知观察者

用的集合框架是 Vector 集合框架,为什么呢?是从线程安全的角度去考虑的

同时的删除 观察者,又通知/

是否有替代类?
因为 arraylist 非线程安全
CopyOnWriteArrayList . 是线程安全的

Android 中的应用

回调模式

Onclick()

一对一

BaseAdapter

listview 的 notifyDataChanged

    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }

看看这个类

public class DataSetObservable extends Observable<DataSetObserver> {
    /**
     * Invokes {@link DataSetObserver#onChanged} on each observer.
     * Called when the contents of the data set have changed.  The recipient
     * will obtain the new contents the next time it queries the data set.
     */
    public void notifyChanged() {
        synchronized(mObservers) {
            // since onChanged() is implemented by the app, it could do anything, 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();
            }
        }
    }

使用了倒序的遍历 为什呢? 避免观察者列表 删除的时候数据的同步问题

看看 BaseAdapter 中的注册

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

这就是观察者

看AbsListView的 setAdapter 往下走

AdapterView 有个内部类

class AdapterDataSetObserver extends DataSetObserver {
}

看代码

class 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 with new data.
            if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
                    && mOldItemCount == 0 && mItemCount > 0) {
                AdapterView.this.onRestoreInstanceState(mInstanceState);
                mInstanceState = null;
            } else {
                rememberSyncState();
            }
            checkFocus();
            requestLayout();
        }
}
总之就是 数据在发生变化时候 最终会调到 requestLayout()

Rxjava 中的观察者

上一篇 下一篇

猜你喜欢

热点阅读