观察者模式

引言

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

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

概念

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

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

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面
  • 一个对象的改变将导致一个或多个其他对象也发生改变
    要是一对一的话 直接用接口的回掉就好了
  • 需要在系统中创建一个出发链
    A 影响 B ,B 影响 C

分析

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

观察者收到通知,做自己的事情。
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 {
    /**
     * 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 中的观察者

你可能感兴趣的:(观察者模式)