之是以說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();
}
}
以上代碼由 薄荷記賬 研發團隊原創并分享,轉載請加注此行。