Androidオブザーバーモード
8616 ワード
コンセプト:
オブジェクト間の1対のマルチ依存性が定義され、1つのオブジェクトがステータスを変更すると、すべての依存者が通知を受け取り、自動的に更新されます.
4つの要素(自己定義):
オブザーバ、オブザーバ、登録タイミング、メソッド呼び出し
2つの実装方法:
観察者は受動的にメッセージ1を受け取る.オブジェクトインタフェースの作成
被観察者の実現ロジック
notifyObserversメソッドでは、オブジェクトのセットを巡ってupdateメソッドが呼び出され、変化した値がオブジェクトに表示されます.2.オブザーバインタフェースの作成
3.観察者の実現と登録は、それぞれの観察者の登録タイミングが異なり、ここでは観察者をインスタンス化する際に登録する
4.更新の呼び出し
観察者は自発的にメッセージ1を受け取る.被観察者は、上記に基づいてgetメソッドを追加し、観察者に所望のデータを得る方法を提供する.
2.観察者は観察者のupdateメソッドを修正し、WeatherDataインスタンスから自分の欲しいデータを直接取得し、不要なものはgetを使わない
Androidでの使用
1.setOnClickListener()一対一を実現する観察者モードまず方法の中でどのように実現ロジックがあるかを直接見る
setOnClickListener()の過程で直接OnClickListenerをListener Infoの変数に割り当てて、それからこの変数はいつ呼び出されますか、次に見てみましょう
performClick()メソッドでonClickメソッドを直接呼び出すのを見ることができますが、それは誰がperformClick()メソッドを呼び出すのか、検索によってViewクラスにナビゲートすると、以下のコードロジックが表示されます.
コードの中で1つのswitch条件を用いて判断し、異なる操作によって相応の論理を実行し、ここを見て明らかにすべきである.Viewという被観察者は、状態の変化を傍受した後、登録されたonClickListenerの中のonClick観察者メソッドを呼び出し、相応の操作を完了し、1対1のモニタリングであるため、集合の遍歴操作はない.2.listView一対多のオブザーバーモードを実現まずは被オブザーバーの実現方式を見よう
BaseAdapterは,DataSetObservable(被観察者)クラスを直接継承するのではなく,組合せによって変数として用いられることがコードから分かる.次に、listViewの親AdapterViewで観察者の実装クラスを見つけます.
そしてメソッドの呼び出しを見て
データ更新があるたびに、このメソッドが呼び出されてデータがリフレッシュされ、メソッドには観察者の集合が遍歴し、統一された実装メソッドonChanged()が呼び出されてデータのリフレッシュが実現されることがわかります.最后に登录して、実は毎回setAdapter()は登录の过程で、コードは贴らないで、兴味のある小さい仲间は自分でソースコードを见ることができます!!!やはりおかず鸟ですが、问题があれば「笑颜」を指摘してくださいね~
オブジェクト間の1対のマルチ依存性が定義され、1つのオブジェクトがステータスを変更すると、すべての依存者が通知を受け取り、自動的に更新されます.
4つの要素(自己定義):
オブザーバ、オブザーバ、登録タイミング、メソッド呼び出し
2つの実装方法:
観察者は受動的にメッセージ1を受け取る.オブジェクトインタフェースの作成
public interface Subject{
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
被観察者の実現ロジック
public class WeatherData implements Subject{
private ArrayList observers;
//
private String temperature;
//
private String humidity;
//
private String pressure;
public WeatherData() {
observers=new ArrayList();
}
/**
*
*/
public void registerObserver(Observer o) {
observers.add(o);
}
/**
*
*/
public void removeObserver(Observer o) {
if(observers.indexOf(o)>=0){
observers.remove(o);
}
}
/**
*
*/
public void notifyObservers() {
for(Observer o:observers){
o.update(temperature, humidity, pressure);
}
}
/**
* ,
* @param temperature
* @param humidity
* @param pressure
*/
public void setNewData(String temperature,String humidity,String pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
notifyObservers();
}
}
notifyObserversメソッドでは、オブジェクトのセットを巡ってupdateメソッドが呼び出され、変化した値がオブジェクトに表示されます.2.オブザーバインタフェースの作成
public interface Observer{
public void update(String temperature,String humidity,String pressure);
}
3.観察者の実現と登録は、それぞれの観察者の登録タイミングが異なり、ここでは観察者をインスタンス化する際に登録する
public class CurrentCodition implements Observer {
private Subject weaterData;
public CurrentCodition(Subject weaterData) {
this.weaterData = weaterData;
weaterData.registerObserver(this);
}
@Override
public void update(String temperature,String humidity,String pressure) {
//
}
}
4.更新の呼び出し
WeatherData weatherData=new WeatherData();
Observer1 observer1=new Observer1(weatherData);
weatherData.setNewData("10", "20", "30");
観察者は自発的にメッセージ1を受け取る.被観察者は、上記に基づいてgetメソッドを追加し、観察者に所望のデータを得る方法を提供する.
public String getTemperature() {
return temperature;
}
public String getHumidity() {
return humidity;
}
public String getPressure() {
return pressure;
}
2.観察者は観察者のupdateメソッドを修正し、WeatherDataインスタンスから自分の欲しいデータを直接取得し、不要なものはgetを使わない
public void update(Observable o, Object arg) {
if(o instanceof WeatherData){
WeatherData data=(WeatherData)o;
this.humidity=data.getHumidity();
this.pressure=data.getPressure();
this.temperature=data.getTemperature();
}
System.out.println(" , ");
}
Androidでの使用
1.setOnClickListener()一対一を実現する観察者モードまず方法の中でどのように実現ロジックがあるかを直接見る
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
setOnClickListener()の過程で直接OnClickListenerをListener Infoの変数に割り当てて、それからこの変数はいつ呼び出されますか、次に見てみましょう
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}
performClick()メソッドでonClickメソッドを直接呼び出すのを見ることができますが、それは誰がperformClick()メソッドを呼び出すのか、検索によってViewクラスにナビゲートすると、以下のコードロジックが表示されます.
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
if (isNestedScrollingEnabled()
&& (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
|| action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
|| action == R.id.accessibilityActionScrollUp
|| action == R.id.accessibilityActionScrollLeft
|| action == R.id.accessibilityActionScrollDown
|| action == R.id.accessibilityActionScrollRight)) {
if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) {
return true;
}
}
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
if (isClickable()) {
performClick();
return true;
}
} break;
case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
if (isLongClickable()) {
performLongClick();
return true;
}
} break;
コードの中で1つのswitch条件を用いて判断し、異なる操作によって相応の論理を実行し、ここを見て明らかにすべきである.Viewという被観察者は、状態の変化を傍受した後、登録されたonClickListenerの中のonClick観察者メソッドを呼び出し、相応の操作を完了し、1対1のモニタリングであるため、集合の遍歴操作はない.2.listView一対多のオブザーバーモードを実現まずは被オブザーバーの実現方式を見よう
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();
}
BaseAdapterは,DataSetObservable(被観察者)クラスを直接継承するのではなく,組合せによって変数として用いられることがコードから分かる.次に、listViewの親AdapterViewで観察者の実装クラスを見つけます.
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;
}
}
そしてメソッドの呼び出しを見て
public void notifyChanged() {
synchronized(mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
}
データ更新があるたびに、このメソッドが呼び出されてデータがリフレッシュされ、メソッドには観察者の集合が遍歴し、統一された実装メソッドonChanged()が呼び出されてデータのリフレッシュが実現されることがわかります.最后に登录して、実は毎回setAdapter()は登录の过程で、コードは贴らないで、兴味のある小さい仲间は自分でソースコードを见ることができます!!!やはりおかず鸟ですが、问题があれば「笑颜」を指摘してくださいね~