带有语法强类型检查的事件总线(EventBus)框架再完善篇
来源:互联网 发布:知天下资源吧帐号 编辑:程序博客网 时间:2024/05/16 08:12
引申阅读:
带有语法强类型检查的事件总线(EventBus)框架(http://blog.csdn.net/z13759561330/article/details/49467737)
简单并快乐着,带有语法强类型检查的事件总线(EventBus)框架完善篇(http://blog.csdn.net/z13759561330/article/details/49486575)
在这一篇中,基于读写分离的思想完善了多线程操作的安装性,读和写不同的容器,采用双容器,写时写入后台容器,写完后交换到前台使用,这样做的好处是我们可以对容器进行并发的读,而不需要加锁,以提高并发性能。
EventBus.java代码如下:
package com.zjg.smart.android.app;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.zjg.smart.utils.DebugUtils;
public class EventBus {
// 采用泛型接口的好处是,编译器自动帮你补全方法
// 如EventBus一样,四种模式的接收者接口
// 每种模式一个接口,按需实现
public interface EventReceiver<E> {
public void onEvent(E event);
}
public interface EventMainThreadReceiver<E> {
public void onEventMainThread(E event);
}
public interface EventBackgroundThreadReceiver<E> {
public void onEventBackgroundThread(E event);
}
public interface EventAsyncReceiver<E> {
public void onEventAsync(E event);
}
private static class SingletonHelper {
public static EventBus instance =new EventBus();
}
private EventBus() {
}
public static EventBus getInstance() {
return SingletonHelper.instance;
}
private HashMap<Class<?>,List<EventBus.EventReceiver<?>>>eventReceiverHashMap = newHashMap<Class<?>, List<EventBus.EventReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventMainThreadReceiver<?>>>eventMainThreadReceiverHashMap = new HashMap<Class<?>,List<EventBus.EventMainThreadReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventBackgroundThreadReceiver<?>>>eventBackgroundThreadReceiverHashMap = new HashMap<Class<?>,List<EventBus.EventBackgroundThreadReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventAsyncReceiver<?>>>eventAsyncReceiverHashMap = newHashMap<Class<?>,List<EventBus.EventAsyncReceiver<?>>>();
// 基于读写分离的思想,读和写不同的容器,采用双容器,写时写入后台容器,写完后交换到前台使用,
// 这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁。
private HashMap<Class<?>,List<EventBus.EventReceiver<?>>>bgEventReceiverHashMap = newHashMap<Class<?>, List<EventBus.EventReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventMainThreadReceiver<?>>>bgEventMainThreadReceiverHashMap = new HashMap<Class<?>,List<EventBus.EventMainThreadReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventBackgroundThreadReceiver<?>>>bgEventBackgroundThreadReceiverHashMap = new HashMap<Class<?>,List<EventBus.EventBackgroundThreadReceiver<?>>>();
private HashMap<Class<?>,List<EventBus.EventAsyncReceiver<?>>>bgEventAsyncReceiverHashMap = newHashMap<Class<?>,List<EventBus.EventAsyncReceiver<?>>>();
private ObjecteventReceiverHashMapWLock = new Object();
private ObjecteventMainThreadReceiverHashMapWLock = new Object();
private ObjecteventBackgroundThreadReceiverHashMapWLock = new Object();
private ObjecteventAsyncReceiverHashMapWLock = new Object();
private void swapEventReceiverHashMap() {
HashMap<Class<?>,List<EventBus.EventReceiver<?>>> tmp = eventReceiverHashMap;
eventReceiverHashMap = bgEventReceiverHashMap;
bgEventReceiverHashMap =tmp;
}
private void swapEventMainThreadReceiverHashMap() {
HashMap<Class<?>, List<EventBus.EventMainThreadReceiver<?>>>tmp =eventMainThreadReceiverHashMap;
eventMainThreadReceiverHashMap =bgEventMainThreadReceiverHashMap;
bgEventMainThreadReceiverHashMap =tmp;
}
private void swapEventBackgroundThreadReceiverHashMap() {
HashMap<Class<?>,List<EventBus.EventBackgroundThreadReceiver<?>>>tmp = eventBackgroundThreadReceiverHashMap;
eventBackgroundThreadReceiverHashMap =bgEventBackgroundThreadReceiverHashMap;
bgEventBackgroundThreadReceiverHashMap =tmp;
}
private void swapEventAsyncReceiverHashMap() {
HashMap<Class<?>,List<EventBus.EventAsyncReceiver<?>>> tmp = eventAsyncReceiverHashMap;
eventAsyncReceiverHashMap =bgEventAsyncReceiverHashMap;
bgEventAsyncReceiverHashMap =tmp;
}
// 订阅事件的方法,相应的有四种模式,这里编译器自动对事件的类型进行检查
// 订阅者必须实现相应类型、相应模式的接收者接口,才能订阅相对应的事件
public <E>void registerEventReceiver(EventReceiver<E>receiver,
Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventReceiverHashMapWLock) {
_registerEventReceiver(receiver,cls);
swapEventReceiverHashMap();
// 交换后再写一遍,保证后台容器与前台容器同步
_registerEventReceiver(receiver,cls);
}
}
private <E>void _registerEventReceiver(EventReceiver<E>receiver,
Class<E> cls) {
List<EventBus.EventReceiver<?>> eventReceiverList = bgEventReceiverHashMap
.get(cls);
if (eventReceiverList ==null) {
eventReceiverList =new LinkedList<EventBus.EventReceiver<?>>();
bgEventReceiverHashMap.put(cls,eventReceiverList);
}
eventReceiverList.add(receiver);
}
public <E>void registerEventMainThreadReceiver(
EventMainThreadReceiver<E> receiver, Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventMainThreadReceiverHashMapWLock) {
_registerEventMainThreadReceiver(receiver,cls);
swapEventMainThreadReceiverHashMap();
_registerEventMainThreadReceiver(receiver,cls);
}
}
private <E>void _registerEventMainThreadReceiver(
EventMainThreadReceiver<E> receiver, Class<E> cls) {
List<EventBus.EventMainThreadReceiver<?>> eventMainThreadReceiverList = bgEventMainThreadReceiverHashMap
.get(cls);
if (eventMainThreadReceiverList ==null) {
eventMainThreadReceiverList =newLinkedList<EventBus.EventMainThreadReceiver<?>>();
bgEventMainThreadReceiverHashMap.put(cls,
eventMainThreadReceiverList);
}
eventMainThreadReceiverList.add(receiver);
}
public <E>void registerEventBackgroundThreadReceiver(
EventBackgroundThreadReceiver<E> receiver, Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventBackgroundThreadReceiverHashMapWLock) {
_registerEventBackgroundThreadReceiver(receiver,cls);
swapEventBackgroundThreadReceiverHashMap();
_registerEventBackgroundThreadReceiver(receiver,cls);
}
}
private <E>void _registerEventBackgroundThreadReceiver(
EventBackgroundThreadReceiver<E> receiver, Class<E> cls) {
List<EventBus.EventBackgroundThreadReceiver<?>> eventBackgroundThreadReceiverList = bgEventBackgroundThreadReceiverHashMap
.get(cls);
if (eventBackgroundThreadReceiverList ==null) {
eventBackgroundThreadReceiverList =newLinkedList<EventBus.EventBackgroundThreadReceiver<?>>();
bgEventBackgroundThreadReceiverHashMap.put(cls,
eventBackgroundThreadReceiverList);
}
eventBackgroundThreadReceiverList.add(receiver);
}
public <E>void registerEventAsyncReceiver(EventAsyncReceiver<E>receiver,
Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventAsyncReceiverHashMapWLock) {
_registerEventAsyncReceiver(receiver,cls);
swapEventAsyncReceiverHashMap();
_registerEventAsyncReceiver(receiver,cls);
}
}
private <E>void _registerEventAsyncReceiver(
EventAsyncReceiver<E> receiver, Class<E>cls) {
List<EventBus.EventAsyncReceiver<?>> eventAsyncReceiverList = bgEventAsyncReceiverHashMap
.get(cls);
if (eventAsyncReceiverList ==null) {
eventAsyncReceiverList =newLinkedList<EventBus.EventAsyncReceiver<?>>();
bgEventAsyncReceiverHashMap.put(cls,eventAsyncReceiverList);
}
eventAsyncReceiverList.add(receiver);
}
// 退订事件,也是相应的四种模式
public <E>void unregisterEventReceiver(EventReceiver<E>receiver,
Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventReceiverHashMapWLock) {
_unregisterEventReceiver(receiver,cls);
swapEventReceiverHashMap();
_unregisterEventReceiver(receiver,cls);
}
}
private <E>void _unregisterEventReceiver(EventReceiver<E>receiver,
Class<E> cls) {
List<EventBus.EventReceiver<?>> eventReceiverList = bgEventReceiverHashMap
.get(cls);
if (eventReceiverList !=null) {
eventReceiverList.remove(receiver);
}
}
public <E>void unregisterEventMainThreadReceiver(
EventMainThreadReceiver<E> receiver, Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventMainThreadReceiverHashMapWLock) {
_unregisterEventMainThreadReceiver(receiver,cls);
swapEventMainThreadReceiverHashMap();
_unregisterEventMainThreadReceiver(receiver,cls);
}
}
private <E>void _unregisterEventMainThreadReceiver(
EventMainThreadReceiver<E> receiver, Class<E> cls) {
List<EventBus.EventMainThreadReceiver<?>> eventMainThreadReceiverList = bgEventMainThreadReceiverHashMap
.get(cls);
if (eventMainThreadReceiverList !=null) {
eventMainThreadReceiverList.remove(receiver);
}
}
public <E>void unregisterEventBackgroundThreadReceiver(
EventBackgroundThreadReceiver<E> receiver, Class<E> cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventBackgroundThreadReceiverHashMapWLock) {
_unregisterEventBackgroundThreadReceiver(receiver,cls);
swapEventBackgroundThreadReceiverHashMap();
_unregisterEventBackgroundThreadReceiver(receiver,cls);
}
}
private <E>void _unregisterEventBackgroundThreadReceiver(
EventBackgroundThreadReceiver<E> receiver, Class<E> cls) {
List<EventBus.EventBackgroundThreadReceiver<?>> eventBackgroundThreadReceiverList = bgEventBackgroundThreadReceiverHashMap
.get(cls);
if (eventBackgroundThreadReceiverList !=null) {
eventBackgroundThreadReceiverList.remove(receiver);
}
}
public <E>void unregisterEventAsyncReceiver(
EventAsyncReceiver<E> receiver, Class<E>cls) {
if (receiver ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "receiver ==null");
}
if (cls ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "cls ==null");
}
synchronized (eventAsyncReceiverHashMapWLock) {
_unregisterEventAsyncReceiver(receiver,cls);
swapEventAsyncReceiverHashMap();
_unregisterEventAsyncReceiver(receiver,cls);
}
}
private <E>void _unregisterEventAsyncReceiver(
EventAsyncReceiver<E> receiver, Class<E>cls) {
List<EventBus.EventAsyncReceiver<?>> eventAsyncReceiverList = eventAsyncReceiverHashMap
.get(cls);
if (eventAsyncReceiverList !=null) {
eventAsyncReceiverList.remove(receiver);
}
}
// 事件发送方法,对事件的类型和模式都进行匹配
public <E>void post(final Eevent) {
if (event ==null) {
throw new NullPointerException(DebugUtils.STACK_TRACE()
+ "event ==null");
}
List<EventReceiver<?>> eventReceiverList =null;
eventReceiverList = eventReceiverHashMap.get(event.getClass());
if (eventReceiverList !=null) {
for (inti = 0, sz =eventReceiverList.size(); i < sz; i++) {
EventBus.EventReceiver<E> eventReceiver = (EventReceiver<E>)eventReceiverList
.get(i);
if (eventReceiver !=null) {
eventReceiver.onEvent(event);
}
}
}
List<EventMainThreadReceiver<?>> eventMainThreadReceiverList = null;
eventMainThreadReceiverList =eventMainThreadReceiverHashMap.get(event
.getClass());
if (eventMainThreadReceiverList !=null) {
for (inti = 0, sz =eventMainThreadReceiverList.size(); i < sz; i++) {
final EventBus.EventMainThreadReceiver<E>eventMainThreadReceiver = (EventMainThreadReceiver<E>)eventMainThreadReceiverList
.get(i);
if (eventMainThreadReceiver !=null) {
if (Thread.currentThread() == Looper.getMainLooper()
.getThread()) {
// 如果当前线程是主线程,直接回调
eventMainThreadReceiver.onEventMainThread(event);
} else {
// 如果不是主线程,寄送到主线程回调
new Handler(Looper.getMainLooper())
.post(new Runnable() {
@Override
publicvoid run() {
//TODO自动生成的方法存根
eventMainThreadReceiver
.onEventMainThread(event);
}
});
}
}
}
}
List<EventBus.EventBackgroundThreadReceiver<?>> eventBackgroundThreadReceiverList = null;
eventBackgroundThreadReceiverList =eventBackgroundThreadReceiverHashMap
.get(event.getClass());
if (eventBackgroundThreadReceiverList !=null) {
for (inti = 0, sz =eventBackgroundThreadReceiverList.size(); i < sz; i++) {
final EventBus.EventBackgroundThreadReceiver<E>eventBackgroundThreadReceiver = (EventBackgroundThreadReceiver<E>)eventBackgroundThreadReceiverList
.get(i);
if (eventBackgroundThreadReceiver !=null) {
if (Thread.currentThread() != Looper.getMainLooper()
.getThread()) {
// 如果当前线程不是主线程,直接回调
eventBackgroundThreadReceiver
.onEventBackgroundThread(event);
} else {
// 如果当前线程是主线程,另开线程回调
new Thread() {
publicvoid run() {
eventBackgroundThreadReceiver
.onEventBackgroundThread(event);
};
}.start();
}
}
}
}
List<EventAsyncReceiver<?>> eventAsyncReceiverList =null;
eventAsyncReceiverList =eventAsyncReceiverHashMap
.get(event.getClass());
if (eventAsyncReceiverList !=null) {
for (inti = 0, sz =eventAsyncReceiverList.size(); i < sz; i++) {
final EventBus.EventAsyncReceiver<E>eventAsyncReceiver = (EventAsyncReceiver<E>) eventAsyncReceiverList
.get(i);
if (eventAsyncReceiver !=null) {
new Thread() {
publicvoid run() {
eventAsyncReceiver.onEventAsync(event);
}
}.start();
}
}
}
}
}
在写例程的时候遇到一个小问题,就是按照原先的想法像这样写事件订阅者:
publicclass MainActivity extends Activityimplements EventMainThreadReceiver<FirstEvent>,EventMainThreadReceiver<SecondEvent>{
编译会给个提示:“不能使用不同的参数 EventBus.EventMainThreadReceiver<SecondEvent> 和 EventBus.EventMainThreadReceiver<FirstEvent> 来多次实现接口 EventMainThreadReceiver”,这个问题估计是Java泛型的类型擦出引起的。
后来想了一个办法巧妙的给解决了,只是代码会稍微复杂点,我解释一下,由于Java语言的机制问题,不让在同一个子类上,实现两个以上的泛型接口(即使泛型的类型参数不同)。那么我就在不同的子类上实现呗,我让这些子类都成为事件订阅者的内部类:
public class MainActivity extends Activity {
EventMainThreadReceiver<FirstEvent> firstEventMainThreadReceiver = null;
EventMainThreadReceiver<SecondEvent> secondEventMainThreadReceiver = null;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 订阅事件
firstEventMainThreadReceiver =new EventMainThreadReceiver<FirstEvent>() {
@Override
public void onEventMainThread(FirstEvent event) {
// TODO
String msg = "onEventMainThread" + event;
Log.i("eventbus",msg);
tv.setText(msg);
Toast.makeText(MainActivity.this,msg, Toast.LENGTH_SHORT)
.show();
}
};
EventBus.getInstance().registerEventMainThreadReceiver(
firstEventMainThreadReceiver, FirstEvent.class);
secondEventMainThreadReceiver =new EventMainThreadReceiver<SecondEvent>() {
@Override
public void onEventMainThread(SecondEvent event) {
// TODO
String msg = "onEventMainThread" + event;
Log.i("eventbus",msg);
tv.setText(msg);
Toast.makeText(MainActivity.this,msg, Toast.LENGTH_SHORT)
.show();
}
};
EventBus.getInstance().registerEventMainThreadReceiver(
secondEventMainThreadReceiver, SecondEvent.class);
...
这样也可以达到预期效果,虽然代码会增多一些,但这无不是一个折衷的办法。
完整例子请到这里下载(http://download.csdn.net/detail/z13759561330/9229093)。
- 带有语法强类型检查的事件总线(EventBus)框架再完善篇
- 简单并快乐着,带有语法强类型检查的事件总线(EventBus)框架完善篇
- 带有语法强类型检查的事件总线(EventBus)框架
- EventBus事件总线框架的使用
- EventBus,一个可以在Activity、Fragment、Service之间传递任意类型数据的事件总线框架
- 发布 / 订阅的事件总线(eventBus)
- 事件总线分发库EventBus框架的简单使用
- Android事件总线框架之EventBus(3.0为例)
- android中EventBus框架(订阅事件总线)
- 事件总线-EVENTBUS的使用
- EventBus事件总线的使用
- EventBus事件总线的使用
- 使用事件总线框架EventBus和Otto
- 使用事件总线框架EventBus和Otto
- 使用事件总线框架EventBus和Otto
- 浅谈Android事件总线框架EventBus
- Android 认识EventBus轻量级事件总线框架
- 事件总线EventBus Android开源库的使用
- 分析一个设备驱动程序结构
- 【机器学习算法】之logistic回归
- ActionBar(Undone)
- Mysql Event SCHEDULE Job 定时任务
- http请求
- 带有语法强类型检查的事件总线(EventBus)框架再完善篇
- AlertDialog
- Java面试集锦06-继承和多态
- 八数码--HDU - 1043 Eight
- 10月英语启航
- DOJO组件生命周期(the life cycle of dojo widget)
- 自定义NavigationController(根据自定义UIBarButtonItem+ZZ)快速创建
- Git常用命令备忘
- BigPipe facebook