浅谈EventBus源码 - xulijun6564/Myblog GitHub Wiki

在去年两周一次的技术分享会上,我分享的主题是《EventBus源码解析》,分享流程是按照EventBus的使用方式,一步一步去解读源码是怎么实现功能的。将其放在公司博客上,更加方便android小伙伴去查阅、测试、理解和思考。(现在转到我自己的文档下面)

里面包含EventBus的来由历史,优缺点,源码和源码介绍的ppt,以及测试demo,接下来的篇幅就不再重复描述,老司机在会议上告诉我们如果要使用广播的地方,我们尽量都使用这个EventBus,它的便捷我们应该毋庸置疑啦。

EventBus的使用

其实EventBus的使用非常简单,只需要简单的四步。在我们常用的功能实现上,一般情况也只需要围绕这四步做处理。当然他还有一些其他功能,但是在我们的项目中没有进行使用

以Activity为例:

(1)在onCreate()中进行订阅:


EventBus.getDefault().register(this);// 第一种实现方式
EventBus.builder().build().register(this);// 第2种实现方式
						

(2)在此类中写一个onEVent()方法:


public void onEvent(TestAEvent testAEvent) {
           text_test.setText("testAEvent---AAAAA");
   }
				  	

(3)在onDestroy()中进行取消订阅:


EventBus.getDefault().unregister(this);
							 

(4)在需要通知订阅的这个activity进行响应的时候,发出一个事件:


EventBus.getDefault().post(new TestAEvent());
								 		 

以上4步是必不可少的,少了不同的步骤都会有不同的影响,比如少了第(1)步,没有订阅你想要的功能当然不会实现,或者少了第(2)步,EventBus库会报出异常,导致闪退等。

接下来按照步骤理解:

第(1)(3)这两步是要同时出现的,第(1)进行订阅,第(3)进行取消订阅

第(1)步,源码提供的订阅方式有两种,但是测试发现第二种方式出现订阅不成功(源码中有漏洞,但是没有发现),建议都使用第一种方式,第(3)步,取消订阅,如果不去执行,从源码中发现在post消息的时候还是会去轮询查找这个订阅者,然后调用他的onEvent()方法,然而这是完全没有意义的,不必要的操作为何我们要让它去做呢,本来如果订阅者越多,其实EventBus的压力越大,效率就会变低。

第(2)(4)步也是相结合出现使用的,第(2)步是接收回调消息,第(4)步是发送消息,只有发送了消息,才能接收消息嘛。

第(2)步接收消息的回调方法onEVent(),在这个方法中做我们想要的工作。首先这个方法必须要是public,因为在源码是使用反射的方式进行回调,如果不是public,那么在其他地方必然不能调用。(哈哈,这里老司机告诉我,一看手动写一个不是复写不是实现的方法,平白无故的写个这样的方法,一看就知道是反射,你看出来了吗?);其次这个返回值,定义返回什么类型没有关系,因为返回什么也使用不到,一般定义void;然后就是这个非常重要的形式参数,这个参数跟第(4)步发送的消息有着直接关系,这也是第(4)步最主要的功能,发送不同类型的消息,如果想要指定的订阅者去做指定的功能,那么在第(4)步.post(new TestAEvent()); 的时候发送一个特定的对象,在第(2)步接受的形式参数也是这个对象的时候,这个onEvent()方法才会起到作用。即使这样一对一的对象去对应执行,也会出现一种情况,有可能在某种情况我们会循环唤起这个activity,那么这个activity就订阅了多次,如果发送一个这样的对象消息,这个时候,前面循环唤起的activity都会在onEvent()方法得到回调,但是我们只想要一个activity执行,这个时候就需要在这个参数对象中添加一个特定的变量识别,这个变量要有唯一性,在发送的时候将这个对象的变量定义好,然后在接收消息的回调方法中进行判断。

项目一般不会用到其他功能:
从一个activity向另一个activity传递参数

第一个activity跳转的地方先发送一个Sticky的消息postSticky():


EventBus.getDefault().postSticky(new TestAEvent());
		//如果post了两个是以后面那个为准
TestEvent event1 = new TestEvent("我想传一个bean1111到第二个activity");
EventBus.getDefault().postSticky(event1 );
TestEvent event2 = new TestEvent("我想传一个bean2222到第二个activity");
EventBus.getDefault().postSticky(event2);//这个会覆盖前面那个
		//remove掉前面发送的消息
// EventBus.getDefault().removeStickyEvent(event2);//这样remove为啥第一个也不在了呢?因为事件实际只有一个,后面一个覆盖了前面那个
//  EventBus.getDefault().removeStickyEvent(event2.getClass());//这样也可以remove掉
Intent intent = new Intent(EFirstActivity.this,EStickyActivity.class);
this.startActivity(intent);
						 
第二个activity初始化并接收:

(1)EventBus.getDefault().registerSticky(this); // 订阅一个sticky事件 (2)实现onEvent()方法就能接收到第一个activity定义并且发送的消息事件


	 public void onEvent(TestEvent testEvent) {
           text_test.setText(testEvent.testStr);
   }
		 
⚠️ **GitHub.com Fallback** ⚠️