设计模式---Android中的观察者模式

一、意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于他的对象多得到通知并自动更新。
二、参与者:
(1)目标(被观察者)
(2)观察者
(3)通知者(也就是1、2的桥梁)
三、Android中观察者模式的具体体现:
(1)Android ListView 中观察者模式的应用。
首相是目标(被观察者):

import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;

/**
 * Common base class of common implementation for an {@link Adapter} that can be
 * used in both {@link ListView} (by implementing the specialized
 * {@link ListAdapter} interface) and {@link Spinner} (by implementing the
 * specialized {@link SpinnerAdapter} interface).
 */
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 observers that the underlying data has been changed
     * and any View reflecting the data set should refresh itself.
     */
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }

    /**
     * Notifies the attached observers that the underlying data is no longer valid
     * or available. Once invoked this adapter is no longer valid and should
     * not report further data set changes.
     */
    public void notifyDataSetInvalidated() {
        mDataSetObservable.notifyInvalidated();
    }

    // 省略无关代码
}

 

   

package android.database;

/**
 * A specialization of {@link Observable} for {@link DataSetObserver}
 * that provides methods for sending notifications to a list of
 * {@link DataSetObserver} objects.
 */
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();
            }
        }
    }

    /**
     * Invokes {@link DataSetObserver#onInvalidated} on each observer.
     * Called when the data set is no longer valid and cannot be queried again,
     * such as when the data set has been closed.
     */
    public void notifyInvalidated() {
        synchronized (mObservers) {
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onInvalidated();
            }
        }
    }
}

   

 

package android.database;

import java.util.ArrayList;

/**
 * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
 *
 * This abstract class is intended to be subclassed and specialized to maintain
 * a registry of observers of specific types and dispatch notifications to them.
 *
 * @param T The observer type.
 */
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 observers.
     */
    public void unregisterAll() {
        synchronized(mObservers) {
            mObservers.clear();
        }
    }
}

其次是观察者:

public class ListView extends AbsListView {
	
		// 省略无关代码
	   @Override
	    public void setAdapter(ListAdapter adapter) {

		        // 省略无关代码
	        if (mAdapter != null) {
	        	// 省略无关代码
	            mDataSetObserver = new AdapterDataSetObserver();
	            mAdapter.registerDataSetObserver(mDataSetObserver);
	          // 省略无关代码
	    }
	
	// 省略无关代码
}

public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
ViewTreeObserver.OnTouchModeChangeListener,
RemoteViewsAdapter.RemoteAdapterConnectionCallback {
	
	// ...
	  class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
	        @Override
	        public void onChanged() {
	            super.onChanged();
	            if (mFastScroll != null) {
	                mFastScroll.onSectionsChanged();
	            }
	        }

	        @Override
	        public void onInvalidated() {
	            super.onInvalidated();
	            if (mFastScroll != null) {
	                mFastScroll.onSectionsChanged();
	            }
	        }
	    }
		// ...
}

public abstract class AdapterView<T extends Adapter> extends ViewGroup {
	
	//...
	   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();
	        }

	        @Override
	        public void onInvalidated() {
	            mDataChanged = true;

	            if (AdapterView.this.getAdapter().hasStableIds()) {
	                // Remember the current state for the case where our hosting activity is being
	                // stopped and later restarted
	                mInstanceState = AdapterView.this.onSaveInstanceState();
	            }

	            // Data is invalid so we should reset our state
	            mOldItemCount = mItemCount;
	            mItemCount = 0;
	            mSelectedPosition = INVALID_POSITION;
	            mSelectedRowId = INVALID_ROW_ID;
	            mNextSelectedPosition = INVALID_POSITION;
	            mNextSelectedRowId = INVALID_ROW_ID;
	            mNeedSync = false;

	            checkFocus();
	            requestLayout();
	        }

	        public void clearSavedState() {
	            mInstanceState = null;
	        }
	    }
	
	//...
	
	
}

最后就是他们之间的媒介,既然是媒介肯定两者中都有体现,在被观察者中一般是一个集合:BaseAdapter中有体现:

 private final DataSetObservable mDataSetObservable = new DataSetObservable();
在ListView中:

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

其他的自己体会才能理解精髓。


         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值