我們們通常會遇到這樣一個問題,從MainActivity跳轉到BActivity,在BActivity中我們做了一些操作,需要MainActivity更新界面,我們經常會用startActivityForResult來操作。但是如果是MainActivity —> ….. —>BActivity 中間跳轉了多個Activity,用這個方法豈不是很複雜,當然有的朋友會在MainActivity類裏面註冊一個BroadcastReceiver,當需要MainActivity進行相關的操作時,只需要在BActivity裏面sendBroadcast即可,當然這個辦法也是可行的。但是像廣播這種重量級選手,我們能不用還是儘量不用。
在這裏我們將用觀察者模式實現一個類似廣播的通知類。
一、介紹
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,讓它們能夠自動更新自己。
抽象主題角色(被觀察者):把所有對觀察者對象的引用保存在一個集合中,每個抽象主題角色都可以有任意數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現。
抽象消息訂閱者角色(觀察者):爲所有具體的觀察者定義一個接口,在得到主題的通知時更新自己。
具體主題角色(被觀察者):在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色通常用一個子類實現。
具體消息訂閱者角色(觀察者):該角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態相協調。通常用一個子類實現。如果需要,具體觀察者角色可以保存一個指向具體主題角色的引用。
二、代碼實現
1. 抽象主題角色
package com.example.observerdemo.observer;
/**
* 被觀察者
*/
public interface IObservable {
/**
* 向消息訂閱隊列添加訂閱者
*/
void deleteObserver(IObserver observer);
/**
* 刪除指定訂閱者
*/
void addObserver(IObserver observer);
/**
* 通知消息訂閱隊列裏的每一個訂閱者
* @param data 給訂閱者傳遞的參數
* @param flag 標示
*/
void notifyObservers(Object data,int flag);
}
2.抽象消息訂閱者
package com.example.observerdemo.observer;
/**
* 消息訂閱者(觀察者)
*/
public interface IObserver {
/**
* 當消息發佈者發佈消息的時候調用該方法
* @param observable 消息發佈者
* @param msg 發佈的消息內容
* @param flag 消息的類型標記
*/
void onMessageReceived(IObservable observable, Object msg, int flag);
}
3.具體主題角色(被觀察者)
package com.example.observerdemo.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 被觀察者的具體化,該類負責給觀察者發送消息
* 參考 {@link java.util.Observable}
*/
public class EventObservable implements IObservable{
/**
* 存放消息訂閱者
*/
List<IObserver> observers = new ArrayList<IObserver>();
public EventObservable() {
}
/**
* 向消息訂閱隊列添加訂閱者
*/
@Override
public void addObserver(IObserver observer) {
if (observer == null) {
throw new NullPointerException("EventObservable == null");
}
synchronized (this) {
if (!observers.contains(observer)) {
observers.add(observer);
}
}
}
/**
* 獲得訂閱者的數量
*/
public int countObservers() {
return observers.size();
}
/**
* 刪除指定訂閱者
*/
@Override
public synchronized void deleteObserver(IObserver observer) {
observers.remove(observer);
}
/**
* 刪除所有訂閱者.
*/
public synchronized void deleteObservers() {
observers.clear();
}
/**
* 通知消息訂閱隊列裏的每一個訂閱者
*/
public void notifyObservers(int flag) {
notifyObservers(null,flag);
}
/**
* 通知消息訂閱隊列裏的每一個訂閱者
* @param data 給訂閱者傳遞的參數
*/
@SuppressWarnings("unchecked")
@Override
public void notifyObservers(Object data,int flag) {
int size = 0;
IObserver[] arrays = null;
synchronized (this) {
size = observers.size();
arrays = new IObserver[size];
observers.toArray(arrays);
}
if (arrays != null) {
for (IObserver observer : arrays) {
observer.onMessageReceived(this, data,flag);
}
}
}
}
4.具體消息訂閱者角色(觀察者)
public class EventObserver implements IObserver{
/**
* 重寫自 IObserver 的方法
* @param observable 消息發佈者
* @param msg 發佈的消息內容
* @param flag 消息的類型標記
*/
@Override
public void onMessageReceived(IObservable observable, Object msg, int flag) {
switch (flag) {
case ObserverHolder.STAFF_ADD: // 添加員工
Log.e("DEVICE_ADD", (String) msg);
count++;
break;
case ObserverHolder.STAFF_DELETE: //刪除員工
Log.e("DEVICE_DELETE", (String) msg);
count--;
break;
}
txtContent.setText("還有"+count+"位員工");
}
}
5.接下來再寫一個訂閱模式管理類,方便調用
package com.example.observerdemo.observer;
/**
* 訂閱模式管理類
*/
public class ObserverHolder {
/**
* 添加員工
*/
public static final int STAFF_ADD = 0;
/**
* 刪除員工
*/
public static final int STAFF_DELETE = 1;
/**
* 更改員工信息
*/
public static final int STAFF_ALTER = 2;
private static ObserverHolder instance;
private EventObservable observable;
private ObserverHolder() {
observable = new EventObservable();
}
public static ObserverHolder getInstance() {
if (instance == null) {
synchronized (ObserverHolder.class) {
if (instance == null) {
instance = new ObserverHolder();
}
}
}
return instance;
}
/**
* 將消息接收者註冊進來
* (如果將Activity作爲訂閱者在此註冊的時候,切記在onDestroy()裏面移除註冊,否則可能導致內存泄露)
* @param observer
*/
public void register(IObserver observer){
observable.addObserver(observer);
}
/**
* 將消息接收者移除註冊
*/
public void unregister(IObserver observer){
observable.deleteObserver(observer);
}
/**
* 給訂閱者發生消息
* @param data
*/
public void notifyObservers(String data,int flag){
observable.notifyObservers(data,flag);
}
}
6.使用
EventObserver observer = new EventObserver();
ObserverHolder.getInstance().register(observer); //註冊
ObserverHolder.getInstance().unregister(observer); //不用的時候釋放註冊
再看一下調用
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_add:
ObserverHolder.getInstance().notifyObservers("添加員工",ObserverHolder.STAFF_ADD);
break;
case R.id.btn_delete:
ObserverHolder.getInstance().notifyObservers("刪除員工",ObserverHolder.STAFF_DELETE);
break;
}
}
Demo地址:
https://code.csdn.net/chengliang0315/observerdemo/tree/master
http://download.csdn.net/detail/chengliang0315/9696796