一、类图
阅读笔者文章的读者会发现,笔者的文章中几乎没有任何与代码相关的类图或者流程图。按理来说,使用图文结合的形式来分析源码,可以使读者更容易接受,且能更快地掌握。究其原因,还是笔者比较懒,不太愿意去画这些东西。因此,这里为了让读者有个整体的概念,就借用了网友的关于EventBus的详细类图,在此对这位网友表示感谢!
二、常见错误及原因
这一小节,我们来看看使用EventBus时遇到的一些错误,并将错误发生的原因梳理出来,便于读者更好地使用EventBus。
错误描述:"Subscriber " + subscriber.getClass() + " already registered to event "+ eventType
原因:该问题是由于在同一个订阅类里面,重复订阅了同名且事件类型相同的订阅方法(以@Subscribe标记)
出现场景:EventBus.getDefault().register(this)写在Activity A的onStart()方法里,此时从Activity A启动Activity B,再从Activity B回退到Activity A,则此时又会执行Activity A的onStart()方法,导致又执行了一遍register操作,进而被认为重复订阅
解决方法:
1.使用EventBus.getDefault().isRegistered(this)判断;
2.更换register位置
错误描述:"Subscriber to unregister was not registered before: " + subscriber.getClass()
原因:该订阅类之前没有注册过,此时却要解除注册,从而引发该问题
出现场景:注册与解除注册没有在适当位置成对出现
解决方法:注册与解除注册成对出现
错误描述:"No subscribers registered for event " + eventClass
原因:没有订阅该类事件
解决方法:订阅该类事件
错误描述:"Unknown thread mode: " + subscription.subscriberMethod.threadMode
原因:使用了EventBus没有定义过的线程模式
解决方法:必须使用EventBus提供的线程模式
当调用cancelEventDelivery方法时,可能抛出如下四个异常,致使程序崩溃。请读者正视,该方法主要是用于高优先级的订阅方法里取消事件向低优先级订阅方法的传递,且只能在POSTING线程模式下使用,切忌滥用!!!后面会给出使用范例。
错误描述:This method may only be called from inside event handling methods on the posting thread
原因:没有在订阅方法里调用cancelEventDelivery
解决方法:必须在订阅方法里面调用cancelEventDelivery
错误描述:Event may not be null
原因:cancelEventDelivery在订阅方法里调用了,但是订阅方法将事件设置成了null,导致cancelEventDelivery接收到null参数
解决:确保传递给cancelEventDelivery的参数非null
错误描述:Only the currently handled event may be aborted
原因:cancelEventDelivery在订阅方法里调用了,但参数并非订阅方法传进来的事件对象,而是其他对象
解决方法:确保要取消的事件是当前正在被处理的事件
错误描述:event handlers may only abort the incoming event
原因:cancelEventDelivery调用时所处的订阅方法的线程模式不是Posting
解决方法:cancelEventDelivery必须在Posting线程模式的订阅方法里执行
cancelEventDelivery使用范例如下:
class Event {
}
---------------------------------------------------------------------------------------------------------------------
Event event = new Event();
---------------------------------------------------------------------------------------------------------------------
@Subscribe(threadMode = ThreadMode.Posting, priority = 1000)
public void onEventHigh(Event event) {
Log.d("CancelTest", "subscribe high");
try {
EventBus.getDefault().cancelEventDelivery(event);
} catch (EventBusException e) {
Log.e("Test", e.getMessage());
}
}
@Subscribe(threadMode = ThreadMode.Posting, priority = 100)
public void onEventLow(Event event) {
Log.d("CancelTest", "subscribe low");
}