简单并快乐着,带有语法强类型检查的事件总线(EventBus)框架完善篇

简单并快乐着,带有语法强类型检查的事件总线(EventBus)框架完善篇

 

在上一篇(http://blog.csdn.net/z13759561330/article/details/49467737)中提出一个改进的框架,之后小弟花了一点时间进行完善,代码其实很简单(相对于GreenRobot的EventBus来说):

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 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 =new HashMap<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 =new HashMap<Class<?>, List<EventBus.EventAsyncReceiver<?>>>();

 

    // 订阅事件的方法,相应的有四种模式,这里篇译器自动对事件的类型进行检查

    // 订阅者必须实现相应类型、相应模式的接收者接口,才能订阅相对应的事件

    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");

       }

       List<EventBus.EventReceiver<?>> eventReceiverList = eventReceiverHashMap

              .get(cls);

       if (eventReceiverList ==null) {

           eventReceiverList =new LinkedList<EventBus.EventReceiver<?>>();

           eventReceiverHashMap.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");

       }

       List<EventBus.EventMainThreadReceiver<?>> eventMainThreadReceiverList = eventMainThreadReceiverHashMap

              .get(cls);

       if (eventMainThreadReceiverList ==null) {

           eventMainThreadReceiverList =new LinkedList<EventBus.EventMainThreadReceiver<?>>();

           eventMainThreadReceiverHashMap

                  .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");

       }

       List<EventBus.EventBackgroundThreadReceiver<?>> eventBackgroundThreadReceiverList = eventBackgroundThreadReceiverHashMap

              .get(cls);

       if (eventBackgroundThreadReceiverList ==null) {

           eventBackgroundThreadReceiverList =new LinkedList<EventBus.EventBackgroundThreadReceiver<?>>();

           eventBackgroundThreadReceiverHashMap.put(cls,

                  eventBackgroundThreadReceiverList);

       }

       eventBackgroundThreadReceiverList.add(receiver);

    }

 

    public <E>void registerAsyncReceiver(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");

       }

       List<EventBus.EventAsyncReceiver<?>> eventAsyncReceiverList = eventAsyncReceiverHashMap

              .get(cls);

       if (eventAsyncReceiverList ==null) {

           eventAsyncReceiverList =new LinkedList<EventBus.EventAsyncReceiver<?>>();

           eventAsyncReceiverHashMap.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");

       }

       List<EventBus.EventReceiver<?>> eventReceiverList = eventReceiverHashMap

              .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");

       }

       List<EventBus.EventMainThreadReceiver<?>> eventMainThreadReceiverList = eventMainThreadReceiverHashMap

              .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");

       }

       List<EventBus.EventBackgroundThreadReceiver<?>> eventBackgroundThreadReceiverList = eventBackgroundThreadReceiverHashMap

              .get(cls);

       if (eventBackgroundThreadReceiverList !=null) {

           eventBackgroundThreadReceiverList.remove(receiver);

       }

    }

 

    public <E>void unregisterAsyncReceiver(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");

       }

       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 =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 = 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 = 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 =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();

              }

           }

       }

    }

}

 

 

 

上例子,借用harvic880925的博客例程
(http://blog.csdn.net/harvic880925/article/details/40660137),在此表示感谢!

按照下面的步骤来建立这个工程:

1、基本框架搭建

从第一个Activity跳转到第二个Activity,从第二个Activity发送事件给第一个Activity

MainActivity布局(activity_main.xml

[html]view plaincopy

1.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 

2.        xmlns:tools="http://schemas.android.com/tools" 

3.        android:layout_width="match_parent" 

4.        android:layout_height="match_parent" 

5.        android:orientation="vertical"> 

6.          

7.        <Button  

8.            android:id="@+id/btn_try" 

9.            android:layout_width="match_parent" 

10.          android:layout_height="wrap_content" 

11.          android:text="btn_bty"/> 

12.      <TextView  

13.          android:id="@+id/tv" 

14.          android:layout_width="wrap_content" 

15.          android:layout_height="match_parent"/> 

16.    

17.  </LinearLayout> 

新建一个ActivitySecondActivity布局(activity_second.xml

[html]view plaincopy

1.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 

2.        xmlns:tools="http://schemas.android.com/tools" 

3.        android:layout_width="match_parent" 

4.        android:layout_height="match_parent" 

5.        android:orientation="vertical" 

6.        tools:context="com.harvic.try_eventbus_1.SecondActivity"> 

7.      

8.        <Button  

9.            android:id="@+id/btn_first_event" 

10.          android:layout_width="match_parent" 

11.          android:layout_height="wrap_content" 

12.          android:text="First Event"/> 

13.    

14.  </LinearLayout> 

2、新建一个类FirstEvent,代表一种事件。

[java]view plaincopy

1.    package com.harvic.other; 

2.      

3.    publicclass FirstEvent { 

4.      

5.        private String mMsg; 

6.        public FirstEvent(String msg) { 

7.            // TODO Auto-generatedconstructor stub 

8.            mMsg = msg; 

9.        } 

10.      public String getMsg(){ 

11.          return mMsg; 

12.      } 

13. 

这个类很简单,构造时传进去一个字符串,然后可以通过getMsg()获取出来。

3、在要接收事件的页面注册EventBus

在上面的GIF图片的演示中,大家也可以看到,我们是要在MainActivity中接收发过来的事件,所以我们在MainActivity中订阅事件。

通常我们会在OnCreate()函数中订阅事件,在OnDestroy()函数中退订事件:

package com.zjg.eventbussample;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

 

import com.zjg.smart.android.app.EventBus;

 

public class MainActivity extends Activityimplements

       EventBus.EventMainThreadReceiver<FirstEvent> {

    Button btn;

    TextView tv;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

 

// 订阅事件

       EventBus.getInstance().registerEventMainThreadReceiver(this,

              FirstEvent.class);

 

       btn = (Button) findViewById(R.id.btn_try);

       tv = (TextView) findViewById(R.id.tv);

 

       btn.setOnClickListener(new View.OnClickListener() {

 

           @Override

           public void onClick(View v) {

              // TODO Auto-generated methodstub

              Intent intent = new Intent(getApplicationContext(),

                     SecondActivity.class);

              startActivity(intent);

           }

       });

    }

 

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

       // Inflate the menu; this addsitems to the action bar if it is present.

       getMenuInflater().inflate(R.menu.main,menu);

       return true;

    }

 

    @Override

    public boolean onOptionsItemSelected(MenuItem item) {

       // Handle action bar item clickshere. The action bar will

       // automatically handle clickson the Home/Up button, so long

       // as you specify a parent activityin AndroidManifest.xml.

       int id = item.getItemId();

       if (id == R.id.action_settings) {

           return true;

       }

       return super.onOptionsItemSelected(item);

    }

 

    @Override

    public void onEventMainThread(FirstEvent event) {

       // TODO自动生成的方法存根

       String msg = "onEventMainThread收到了事件:" +event.getMsg();

       Log.d("harvic",msg);

       tv.setText(msg);

       Toast.makeText(this,msg, Toast.LENGTH_LONG).show();

    }

 

    @Override

    protected void onResume() {

       // TODO自动生成的方法存根

       super.onResume();

    }

 

    @Override

    protected void onDestroy() {

       // TODO自动生成的方法存根

       super.onDestroy();

       EventBus.getInstance().unregisterEventMainThreadReceiver(this,

              FirstEvent.class);

    }

}

4、发送事件

EventBus.getInstance().post(

                     new FirstEvent("FirstEvent btn clicked"));

 

完整的SecondActivity.java的代码如下:

 

package com.zjg.eventbussample;

 

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

 

import com.zjg.smart.android.app.EventBus;

 

public class SecondActivity extends Activity {

    private Buttonbtn_FirstEvent;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

       // TODO自动生成的方法存根

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_second);

       btn_FirstEvent = (Button) findViewById(R.id.btn_first_event);

 

       btn_FirstEvent.setOnClickListener(new View.OnClickListener() {

 

           @Override

           public void onClick(View v) {

              // TODO Auto-generated methodstub

              EventBus.getInstance().post(

                     new FirstEvent("FirstEventbtn clicked"));

           }

       });

    }

}

 

5、接收事件

MainActivity中重写onEventMainThreadFirstEvent event),参数就是我们自己定义的类:

在收到Event实例后,我们将其中携带的事件取出,一方面Toast出去,一方面传到TextView中;

@Override

    public void onEventMainThread(FirstEvent event) {

       // TODO自动生成的方法存根

       String msg = "onEventMainThread收到了事件:" +event.getMsg();

       Log.d("harvic",msg);

       tv.setText(msg);

       Toast.makeText(this,msg, Toast.LENGTH_LONG).show();

    }


示例代码下载:http://download.csdn.net/detail/z13759561330/9222231

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值