带有语法强类型检查的事件总线(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)。


0 0
原创粉丝点击