Observer mode-Java Design Mode
Observer mode definition: defines one-to-many dependencies between objects. In this way, when an object changes its state, all its dependent persons will receive notifications and update them automatically. See:
The observer design pattern is also called the publish-subscribe pattern.
It can also be called: publisher + subscriber = observer Mode
In Android, the observer mode instances include: Broadcast Mechanism, ContentObserver registration method, synchronous observer mode, and asynchronous observer mode.
When two objects are loosely coupled, they can still interact, but they do not know the details of each other. The observer provides an object design, which can reduce the coupling between objects and avoid the bidirectional dependency of objects.
For example, in Android, many Listener are in the Observer mode. For example, the OnClickListener of the click event is used to avoid bidirectional dependency of objects.
-- Let's take a look at the Observer mode in Java source code: Observer interface:
package com.daming.java.observer;public interface Observer { void update(Observable observable, Object arg);}
Object Observable class implementation
package com.daming.java.observer;import java.util.Vector;public class Observable { private boolean changed = false; private Vector obs; public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length - 1; i >= 0; i--) ((Observer) arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } /** * Returns the number of observers of this Observable object. * * @return the number of observers of this object. */ public synchronized int countObservers() { return obs.size(); }}
Implementation of MyObserver observer object
package com.daming.java.observer;public class MyObserver implements Observer{ @Override public void update(Observable observable, Object arg) { System.out.println("observable :" + observable + "arg :" + arg); }}
Implementation of MyObserver2 observer object
package com.daming.java.observer;public class MyObserver2 implements Observer{ @Override public void update(Observable observable, Object arg) { System.out.println("observable2 :" + observable + "arg2 :" + arg); }}
Implementation of the TestObserver class
package com.daming.java.observer;public class TestObserver { /** * @param args */ public static void main(String[] args) { Observable observable = new Observable(); MyObserver myObserver = new MyObserver(); MyObserver2 myObserver2 = new MyObserver2(); observable.addObserver(myObserver); observable.addObserver(myObserver2); observable.setChanged(); observable.notifyObservers(14); observable.setChanged(); observable.notifyObservers("I am daming"); }}
Log input result:
observable2 :com.daming.java.observer.Observable@14318bbarg2 :14observable :com.daming.java.observer.Observable@14318bbarg :14observable2 :com.daming.java.observer.Observable@14318bbarg2 :I am damingobservable :com.daming.java.observer.Observable@14318bbarg :I am daming
In Java source code, the above Code uses the push mode. Of course, the PULL mode also exists in the source code, that is, the active query mode. The pull mode is like a broadcast. Some actions are pulled through the onReceive () method, and the ContentObserver can pull the mode. When the database changes, the onChange () method is used () method to call some operations.
-- Next let's take a look at the asynchronous observer mode in Android.
ContentObserver is an asynchronous observer mode. What are the advantages of asynchronous observers? Does not block the callback of the observer. Blocking occurs in synchronous notifications. The response methods of each Observer are serial. If an observer consumes time, it will block other observer recipients, in this way, bugs may occur. Therefore, when designing the program, consider whether to use the asynchronous observer mode to make concurrent processing faster; we use a simple demo to learn the asynchronous observer mode:
Let's take a look at Observer, which is an abstract class in Android.
package cn.daming.observer.design;import android.os.Handler;import android.util.Log;public abstract class Observer { private Handler mHandler; public Observer(Handler handler) { mHandler = handler; } public void onChange() { } public final void dispatchChange() { Log.v("daming", "Observer dispatchChange is mHandler== null :" + (mHandler == null)); if (mHandler == null) { onChange(); } else { mHandler.post(new NotificationRunnable()); } } private final class NotificationRunnable implements Runnable { @Override public void run() { Log.v("daming", "NotificationRunnable dispatchChange is run ... "); Observer.this.onChange(); } }}
Next let's take a look at the implementation of the ObserverService class:
package cn.daming.observer.design;import java.util.ArrayList;import java.util.List;import android.util.Log;public class ObserverService { private int mState; private List
mObservers = new ArrayList
(); public final void registerObserver(Observer observer) { if (!mObservers.contains(observer)) { mObservers.add(observer); } } public final void unregisterObserver(Observer observer) { Log.v("daming", "ObserverService unregisterObserver :"); mObservers.remove(observer); } public void notifyChange() { for (Observer observer : mObservers) { observer.dispatchChange(); } } public int getState() { return mState; } public void setState(int state) { mState = state; notifyChange(); }}
Finally, let's write the test class FirstActivity:
package cn.daming.observer.design;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.daming.designtraning.R;public class FirstActivity extends Activity { private ObserverService mObserverService; private Button mButton; private int mState = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.button); mObserverService = new ObserverService(); mObserverService.registerObserver(mFirstObserver); mObserverService.setState(++mState); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mObserverService.setState(++mState); } }); } @Override protected void onDestroy() { super.onDestroy(); mObserverService.unregisterObserver(mFirstObserver); } @Override protected void onResume() { super.onResume(); } @Override protected void onStop() { super.onStop(); } private Observer mFirstObserver = new Observer(new Handler()) { @Override public void onChange() { int state = mObserverService.getState(); Log.v("daming", "FirstObserver onChange is run state :" + state); } };}
Conclusion: The asynchronous Observer mode is implemented through Handler, that is, a Handler object is uploaded when the Observer object is constructed, so that during callback, it uses handler to send asynchronous messages and execute corresponding operations on the main thread.