在Android中,对于事件的处理有很多,广播broadcast就是一个非常轻量的机制。广播用起来非常方便,比起接口来说好用很多。但是,广播如果使用不当的话,很有可能出现牵一发而动全身的效果,而且代码的可阅读性也比较差。那么废话不多说,我开始介绍今天要实现的简单的事件通知工具。
URM图如下图所示:
这是一个简单的纯传递事件的事件传递机制,不支持传递数据。实现原理:IObserver是观察者(订阅者)的实现接口,ISubject是被观察者(被订阅者)的实现接口,他们中间通过EventManager来进行统一管理和协调。实现的代码如下:
package com.xuexiang.util.observer.normal;
import java.util.HashMap;
import java.util.Map;
/**
* 创建时间:2016-6-5 上午1:12:48
* @author xuexiang
**/
public class EventManager {
/**
* 存放所有被观察者对象的集合
*/
private static Map mEventManager = new HashMap(); //存放各种被观察者对象
/**
* 获取被观察者对象
* @param subjectName 被观察者对象的标记
*/
public static BaseSubject getSubject(String subjectName) {
BaseSubject baseSubject;
if (mEventManager.containsKey(subjectName)) {
baseSubject = mEventManager.get(subjectName);
} else {
baseSubject = new BaseSubject();
mEventManager.put(subjectName, baseSubject);
}
return baseSubject;
}
}
package com.xuexiang.util.observer.normal;
/**
* 被观察者接口
* 创建时间:2016-6-5 上午1:00:25
* @author xuexiang
**/
public interface ISubject {
/**
* 增加观察者
* @param observer 实现IObserver接口的对象
*/
public void register(IObserver observer);
/**
* 删除观察者
* @param observer 实现IObserver接口的对象
*/
public void unregister(IObserver observer);
/**
* 通知所有的观察者
*/
public void notifyObservers();
}
package com.xuexiang.util.observer.normal;
/**
* 观察者接口
* 创建时间:2016-6-5 上午12:55:56
* @author xuexiang
**/
public interface IObserver {
public void onChanged();
public void onInvalidated();
}
package com.xuexiang.util.observer.normal;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
* 被观察者
* 创建时间:2016-6-5 上午1:03:27
* @author xuexiang
**/
public class BaseSubject implements ISubject {
/**
* 存放数据观察者集合
*/
private ArrayList<WeakReference> mObservers = new ArrayList<WeakReference>();
@Override
public void register(IObserver observer) {
WeakReference obs = new WeakReference(observer);
mObservers.add(obs);
}
@Override
public void unregister(IObserver observer) {
WeakReference obs = new WeakReference(observer);
mObservers.remove(obs);
}
@Override
public void notifyObservers() {
ArrayList<WeakReference> observers = mObservers;
int count = observers.size();
for (int i = count - 1; i >= 0; i--) {
WeakReference weak = observers.get(i);
IObserver obs = weak.get();
if (obs != null) {
obs.onChanged();
} else {
observers.remove(i);
}
}
}
}
也许只是单纯的传递事件还不够,那么下面我来给大家介绍支持数据传递的工具。
URM图如下图所示:
这是一个简单的纯传递事件的事件传递机制,支持传递数据,支持多事件的传递。实现原理:ITagObserver是观察者(订阅者)的实现接口,ITagSubject是被观察者(被订阅者)的实现接口,与上文不同的是,在注册观察者的时候,需要额外定义注册的事件Tag,且被观察者通知事件变化的时候,可以传递一个Event对象,通过该对象传递数据。这里注册的事件Tag就类比广播里面的Action,Event就类比广播里面的Intent,他们中间通过TagEventManager来进行统一管理和协调。实现的代码如下:
package com.xuexiang.util.observer.tag;
import java.util.HashMap;
import java.util.Map;
/**
* 创建时间:2016-6-5 下午4:16:29
* @author xuexiang
**/
public class TagEventManager {
private static Map mEventManager = new HashMap(); //存放各种被观察者对象
public static BaseTagSubject getTagSubject(String subjectName) {
BaseTagSubject baseSubject;
if (mEventManager.containsKey(subjectName)) {
baseSubject = mEventManager.get(subjectName);
} else {
baseSubject = new BaseTagSubject();
mEventManager.put(subjectName, baseSubject);
}
return baseSubject;
}
}
package com.xuexiang.util.observer.tag;
import java.util.List;
/**
* 创建时间:2016-6-5 下午2:17:04
* @author xuexiang
**/
public interface ITagSubject {
/**
* 增加观察者
* @param observer 实现ITagObserver接口的对象
* @param eventTagList 注册事件标志的集合
*/
public void register(ITagObserver observer, List eventTagList);
/**
* 删除观察者
* @param observer 实现ITagObserver接口的对象
*/
public void unregister(ITagObserver observer);
/**
* 通知符合要求的观察者
* @param event 同时的具体事件
*/
public void notify(Event event);
}
package com.xuexiang.util.observer.tag;
/**
* 创建时间:2016-6-5 下午2:24:22
* @author xuexiang
**/
public interface ITagObserver {
public void onChanged(Event event);
}
package com.xuexiang.util.observer.tag;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 创建时间:2016-6-5 下午2:15:25
* @author xuexiang
**/
public class BaseTagSubject implements ITagSubject {
//存放数据观察者集合
private Map<WeakReference, List> mObservers = new HashMap<WeakReference, List>();
@Override
public void register(ITagObserver observer, List event ) {
WeakReference obs = new WeakReference(observer);
mObservers.put(obs, event);
}
@Override
public void unregister(ITagObserver observer) {
WeakReference obs = new WeakReference(observer);
mObservers.remove(obs);
}
@Override
public void notify(Event event) {
Iterator<Map.Entry<WeakReference, List>> it = mObservers.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<WeakReference, List> entry = it.next();
WeakReference weak = entry.getKey();
List eventTagList = entry.getValue();
ITagObserver obs = weak.get();
if (obs != null) {
for (String tag : eventTagList) {
if (event.getTag().equals(tag)) {
obs.onChanged(event);
}
}
} else {
it.remove();
}
}
}
}
package com.xuexiang.util.observer.tag;
/**
* 创建时间:2016-6-5 下午2:18:06
* @author xuexiang
**/
public class Event {
private String mTag;
private String mMessage;
/**
* @param tag 消息事件标志
* @param msg 消息事件内容
*/
public Event (String tag, String msg) {
mTag = tag;
mMessage = msg;
}
public String getTag() {
return mTag;
}
public String getMessage() {
return mMessage;
}
}
那么如何使用呢?我们将其和当下最流行的EventBus来进行对比:
首先是注册:
其次是事件通知:
最后就是收到事件通知后的事件处理了:
不过瘾?不要紧,下面有更好的事件通知工具: