1、下面是EventBus3.0的一些用法和源码分析
2、接下来自己实现EventBus的一些简单功能
定义一个EventBus类,主要实现register和post连个方法
public class EventBus {
private static volatile EventBus instace;
private Map
实现SubscribleMethod类,管理EventBus接受方法的一些属性,方法名、注解、参数
public class SubscribleMethod {
private Method method;//方法
private ThreadMode threadMode;//这个方法所在那个线程
private Class eventType;//参数类型
public SubscribleMethod(Method method, ThreadMode threadMode, Class eventType) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public ThreadMode getThreadMode() {
return threadMode;
}
public void setThreadMode(ThreadMode threadMode) {
this.threadMode = threadMode;
}
public Class getEventType() {
return eventType;
}
public void setEventType(Class eventType) {
this.eventType = eventType;
}
}
定义一个ThreadMode枚举类主要是管理EventBus运行在线程的环境
public enum ThreadMode {
PostThread,
}
定义一个Subscribe注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Subscribe {
ThreadMode value() default ThreadMode.PostThread;
}
以上自己定义的EventBus已经完成简单的传递事件功能,
3、下面是使用自定义的EventBus
定义传递事件对象User
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
在第一个页面MainActivity中定义接受事件
@Subscribe
public void receive(User user){
tv.setText("姓名:"+user.getName()+",年龄:"+user.getAge());
}
在第二个页面发送事件
public void onSendDataClick(View view){
User user = new User();
user.setName("张三");
user.setAge(20);
EventBus.getDefault().post(user);
finish();
}
4、事件的效果如下:
5、接下来实现EventBus传递和接收事件的线程切换
在ThreadMode中添加几个枚举
public enum ThreadMode {
PostThread,
MainThread,
BackgroundThread,
}
在添加一个Handler和一个ExecutorService线程池的实例
private Handler handler;
private ExecutorService executorService;
private EventBus(){
handler = new Handler(Looper.getMainLooper());
executorService = Executors.newCachedThreadPool();
}
然后修改EventBus类的post方法
public void post(final Object event){
Set set = eventTypesCache.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()){
final Object subscriber = iterator.next();
List subscribleMethods = eventTypesCache.get(subscriber);
for(final SubscribleMethod subscribleMethod :subscribleMethods){
if(subscribleMethod.getEventType().isAssignableFrom(event.getClass())){
//判断当前接受方法是在哪个线程
switch (subscribleMethod.getThreadMode()){
case PostThread:
invoke(subscriber,subscribleMethod,event);
break;
case MainThread://主线程
//判断发送线程是处在哪个线程 如果发送线程在主线程 则不需要线程切换 否则切换
if (Looper.myLooper() == Looper.getMainLooper()) {//在主线程
invoke(subscriber, subscribleMethod, event);
} else {//在子线程
handler.post(new Runnable() {
@Override
public void run() {
invoke(subscriber, subscribleMethod, event);
}
});
}
break;
case BackgroundThread://后台线程
//判断发送线程是处在哪个线程 如果发送线程是在子线程 则不需要切换 否则切换
if (Looper.getMainLooper() != Looper.myLooper()) {
//发生在子线程
invoke(subscriber, subscribleMethod, event);
} else {//主线程
executorService.execute(new Runnable() {
@Override
public void run() {
invoke(subscriber, subscribleMethod, event);
}
});
}
break;
}
}
}
}
}
最后在修改MainActivity中的接收事件注解
@Subscribe(ThreadMode.BackgroundThread)
public void receive(User user){
Log.e("zxj","Thread name:"+Thread.currentThread().getName());
tv.setText("姓名:"+user.getName()+",年龄:"+user.getAge());
}
ThreadMode的枚举是那个就对应在那个线程中
指定为MainThread时表示是在主线程,指定为BackgroundThread时表示是在子线程,当指定为PostThread(默认)时表示,发送事件(调用post方法)时,post在那个线程,接受就在那个线程
如下图当ThreadMode.BackgroundThread时:
6、最后在提供一个取消注册的方法,在MainActivity的onDestroy方法中调用
public void unregister(Object subscriber) {
if (subscriber != null)
eventTypesCache.remove(subscriber);
}