之所以说200行,并非突出代码的简洁和优秀,而是表达事情的本来面目就是这样,我们没必要把简单的事情搞的那么复杂。
像Greenrobot的EventBus,又是发布/订阅模式,又是线程模型,特别是其基于反射的实现,在Android系统生态越来越封闭的倾向下,适应性将是个问题。无论其搞的什么花花概念,其本质都是基于静态引用。
我们扪心自问,事件总线是干什么的?不就是给你发个消息,让你干件事情嘛!对,静态引用即可。至于怎么弄,请看代码。
以下代码可以保证的是:
1、一看就懂,0学习成本,没有乱七八糟的概念,随自己需要快速二次开发;
2、功能完整,支持事件参数传递,支持发送粘性事件;
3、运行稳定,无额外开销,适应性强;
4、监听器确保在主线程点火,不管从何处发出事件。如有需要可改在子线程点火,但会有额外开销,增加整个项目线程的管控难度。反正我们不需要在子线程,就那么几个破事件,发一下就得了,在主线程快速执行......
一、首先是事件结构定义:重要的是支持各种参数传递
import android.text.TextUtils; import java.io.Serializable; import java.util.HashMap; import java.util.Map; public class Event implements Serializable { private final String name; private Map<String, Serializable> data; public Event(String name) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("Event name is null."); } this.name = name; } public String getName() { return name; } public Event put(String key, Serializable value) { if (data == null) { data = new HashMap<String, Serializable>(); } data.put(key, value); return this; } public Serializable get(String key) { if (data == null) { return null; } return data.get(key); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Event:" + name); if (data != null) { sb.append("," + data.toString()); } return sb.toString(); } }
二、监听器定义
public interface EventListener { public void onReceive(Event event); }
三、事件总线处理器:支持发送粘性事件
import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class EventBus { private static volatile EventBus instance; public static EventBus getInstance() { if (instance == null) { synchronized (EventBus.class) { if (instance == null) { instance = new EventBus(); } } } return instance; } private final Map<String, List<EventListener>> listenerMap = new HashMap<String, List<EventListener>>(); private final Map<String, List<Event>> stickyEvents = new HashMap<String, List<Event>>(); private final Handler handler = new Handler(Looper.getMainLooper()); public void register(String name, EventListener listener) { if (TextUtils.isEmpty(name)) { throw new NullPointerException("name is null."); } if (listener == null) { throw new NullPointerException("listener is null."); } synchronized (listenerMap) { List<EventListener> listeners = listenerMap.get(name); if (listeners == null) { listeners = new ArrayList<EventListener>(); listenerMap.put(name, listeners); } listeners.add(listener); } List<Event> events = null; synchronized (stickyEvents) { events = stickyEvents.get(name); } if (events != null && !events.isEmpty()) { for (int i = 0; i < events.size(); i++) { Event event = events.get(i); fireListener(event, listener); } } } public void unregister(String name, EventListener listener) { if (TextUtils.isEmpty(name)) { return; } if (listener == null) { return; } synchronized (listenerMap) { List<EventListener> listeners = listenerMap.get(name); if (listeners == null) { return; } listeners.remove(listener); } } public void unregisterAll(String name) { if (TextUtils.isEmpty(name)) { return; } synchronized (listenerMap) { listenerMap.remove(name); } } public void clear() { synchronized (listenerMap) { listenerMap.clear(); } } public void sendEvent(String name) { sendEvent(new Event(name)); } public void sendStickyEvent(String name) { sendStickyEvent(new Event(name)); } public void removeStickyEvent(Event event) { if (event == null) { return; } synchronized (stickyEvents) { List<Event> events = stickyEvents.get(event.getName()); if (events == null) { return; } events.remove(event); } } public void removeStickyEvents(String name) { synchronized (stickyEvents) { stickyEvents.remove(name); } } public void clearStickyEvents() { synchronized (stickyEvents) { stickyEvents.clear(); } } public void sendStickyEvent(final Event event) { if (event == null) { throw new NullPointerException("event is null."); } synchronized (stickyEvents) { List<Event> events = stickyEvents.get(event.getName()); if (events == null) { events = new ArrayList<Event>(); stickyEvents.put(event.getName(), events); } events.add(event); } sendEvent(event); } public void sendEvent(final Event event) { if (event == null) { throw new NullPointerException("event is null."); } List<EventListener> listeners = null; synchronized (listenerMap) { listeners = listenerMap.get(event.getName()); } if (listeners == null || listeners.isEmpty()) { return; } for (int i = 0; i < listeners.size(); i++) { final EventListener listener = listeners.get(i); fireListener(event, listener); } } private void fireListener(final Event event, final EventListener listener) { handler.post(new Runnable() { @Override public void run() { listener.onReceive(event); } }); } @Override protected void finalize() throws Throwable { super.finalize(); listenerMap.clear(); } }
以上代码由 薄荷记账 研发团队原创并分享,转载请加注此行。