<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                Android源碼中多處使用觀察者模式,這里就簡單羅列幾處。 觀察者(DataSetObserver),目標(抽象主題、被觀察者)(`Observable<T>`),具體目標(具體主題,具體被觀察者)(DataSetObserverable) **Observer(觀察者)**:DataSetObserver抽象2個方法,一個是觀察數據改變的方法,一個是觀察數據變成無效(或者不可用)時的方法。 源碼路徑:framework/base/core/java/android/database/DataSetObserver.java ~~~ package android.database; /** * Receives call backs when a data set has been changed, or made invalid. The typically data sets * that are observed are {@link Cursor}s or {@link android.widget.Adapter}s. * DataSetObserver must be implemented by objects which are added to a DataSetObservable. */ public abstract class DataSetObserver { /** * This method is called when the entire data set has changed, * most likely through a call to {@link Cursor#requery()} on a {@link Cursor}. */ public void onChanged() { // Do nothing } /** * This method is called when the entire data becomes invalid, * most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a * {@link Cursor}. */ public void onInvalidated() { // Do nothing } } ~~~ **被觀察者** **Subject(目標)**:`Observable<T>`是一個泛型的抽象類,主要功能是注冊和撤銷observer。 源碼路徑:framework/base/core/java/android/database/Observable.java ~~~ /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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(); } } } ~~~ **ConcreateSubject(具體目標)**:實現的方法同Oberver一樣,只不過它是通知`ArrayList<Observer>`下的每個Oberver去執行各自的action。 源碼路徑:framework/base/core/java/android/database/DataSetObservable.java ~~~ /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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(); } } } } ~~~ **ConcreateObserver(具體觀察者)**:具體觀察者的任務是實實在在執行action的類,一般由開發者根據實際情況,自己實現。android也有實現的例子 源碼路徑:framework/base/core/java/android/widget/AbsListView.java ~~~ class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver { @Override public void onChanged() { super.onChanged(); if (mFastScroller != null) { mFastScroller.onSectionsChanged(); } } @Override public void onInvalidated() { super.onInvalidated(); if (mFastScroller != null) { mFastScroller.onSectionsChanged(); } } } ~~~ framework/base/core/java/android/widget/AdapterView.java-AdapterDataSetObserver.java ~~~ class AdapterDataSetObserver extends DataSetObserver { private Parcelable mInstanceState = null; @Override public void onChanged() { mDataChanged = true; mOldItemCount = mItemCount; mItemCount = getAdapter().getCount(); if (DBG) { Xlog.d(TAG, "AdapterView onChanged: mOldItemCount = " + mOldItemCount + ",mItemCount = " + mItemCount + ",getAdapter() = " + getAdapter() + ",AdapterView = " + AdapterView.this, new Throwable("onChanged")); } // 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 (DBG) { Xlog.d(TAG, "AdapterView onInvalidated: mOldItemCount = " + mOldItemCount + ",mItemCount = " + mItemCount + ",getAdapter() = " + getAdapter() + ",AdapterView = " + AdapterView.this, new Throwable("onInvalidated")); } 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,BaseAdapter關聯了一個DataSetObservable對象,并實現registerDataSetObserver和unregisterDataSetObserver兩個方法實現注冊和撤銷Observer,方法notifyDataSetChanged間接調用Observer的實現者的onChange()方法,以達到通知數據改變的作用。使用ListView和BaseAdapter組合時,當BaseAdapter的item改變時,我們經常會調用notifyDataSetChanged(),通知Listview刷新。 #### **BaseAdapter** 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); } /** * 當數據集變化時,通知所有觀察者 */ public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); } ............ } ~~~ 看看mDataSetObservable.notifyChanged()方法: ~~~ /** *數據集觀察者 */ public class DataSetObservable extends Observable<DataSetObserver> { /** * 調用每個觀察者的onChanged函數來通知它們被觀察者發生了變化 */ public void notifyChanged() { synchronized(mObservers) { // 調用所有觀察者的onChanged方式 for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } } ............... } ~~~ 可以看出在mDataSetObservable.notifyChanged()中遍歷所有觀察者,并調用他們的onChanged(),從而告知觀察者發生了什么。 那么觀察者怎么來的,那就是setAdapter方法,其實這些觀察者就是ListView通過setAdapter方法設置Adapter產生的,代碼如下: ~~~ @Override public void setAdapter(ListAdapter adapter) { //如果已經有一個Adapter,那么先注銷該Adapter對應的觀察者 if (mAdapter != null && mDataSetObserver != null) { mAdapter.unregisterDataSetObserver(mDataSetObserver); } resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); } else { mAdapter = adapter; } mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; // AbsListView#setAdapter will update choice mode states. super.setAdapter(adapter); if (mAdapter != null) { mAreAllItemsSelectable = mAdapter.areAllItemsEnabled(); mOldItemCount = mItemCount; //獲取數據的數量 mItemCount = mAdapter.getCount(); checkFocus(); //注意這里:創建一個一個數據集觀察者 mDataSetObserver = new AdapterDataSetObserver(); //將這個觀察者注冊到Adapter中,實際上是注冊到DataSetObservable中 mAdapter.registerDataSetObserver(mDataSetObserver);//注冊觀察者 ......省略 } ~~~ 從程序中可以看出,在設置Adapter時會構建一個AdapterDataSetObserver,這就是所謂的觀察者,最后將這個觀察者注冊到adapter中,這樣觀察者和被觀察者都有了。AdapterDataSetObserver是什么?AdapterDataSetObserver定義在ListView的父類AbsListView中,具體代碼如下 **AdapterDataSetObserver.java** ~~~ class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver { @Override public void onChanged() { super.onChanged(); if (mFastScroller != null) { mFastScroller.onSectionsChanged(); } } @Override public void onInvalidated() { super.onInvalidated(); if (mFastScroller != null) { mFastScroller.onSectionsChanged(); } } } ~~~ 它又繼承自AbsListView的父類AdapterView的AdapterDataSetObserver, 代碼如下 ~~~ class AdapterDataSetObserver extends DataSetObserver { private Parcelable mInstanceState = null; // 上文有說道,調用Adapter的notifyDataSetChanged的時候會調用所有觀察者的onChanged方法,核心實現就在這里 @Override public void onChanged() { mDataChanged = true; mOldItemCount = mItemCount; // 獲取Adapter中數據的數量 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(); // 重新布局ListView、GridView等AdapterView組件 requestLayout(); } // 代碼省略 public void clearSavedState() { mInstanceState = null; } } ~~~ 當ListView的數據發生變化時,調用Adapter的notifyDataSetChanged函數,這個函數又會調用DataSetObservable的notifyChanged函數,這個函數會調用所有觀察者 (AdapterDataSetObserver) 的onChanged方法,在onChanged方法中又會調用ListView重新布局的函數來刷新ListView。**這就是一個觀察者模式**! **總結**:梳理一下整個過程,AdapterView中有一個內部類AdapterDataSetObserver,在ListView中設置Adapter時會構建一個AdapterDataSetObserver,并且注冊到Adapter中,這就是一個觀察者。而Adapter中包含一個數據集可觀察者DataSetObservable,在數據數量發生變更時,開發者手動調用Adapter的notifyDataSetChanged方法,而notifyDataSetChanged實際上會調用DataSetObservable的notifyChanged函數,該函數會遍歷所有觀察者的onChanged方法。在AdapterDataSetObserver的onChanged方法中會獲取Adapter中數據集的新數量,然后調用ListView的requestLayout()方法重新進行布局,更新用戶界面。 **其實,Android用到DataSetObserver的地方很多,Cursor,WebView,Adapter,...非常之多。**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看