前言
EventsBus作为一个一个基于观察者模式的事件发布/订阅框架,想必很多人都已经学习或在学习中,我也不例外,这里记录一下我学习和使用中出现的bug。
如题bug——Subscriber class com.itaem.eventbustest.xxxActivity$2 and its super classes have no public methods with the @Subscribe annotation,即该类及其父类找不到注解方法,以下有4种解决方法
1. 添加注解@Subscribe
如下代码:
@Subscribe
public void onMessage(MessageEvent event){
Toast.makeText(this,event.message,Toast.LENGTH_LONG).show();
}
2.在Fragment应用时,注册传入参数仍为this
register() 方法传入的传输应该为Object类型,而不是Context类型,所以在Fragment中EventBus的注册代码仍然为:
// 传入this,而非getActivity()之类的Context数据
EventBus.getDefault().register(this);
3.关闭R8压缩
这个解决方法从何而来呢?我们可以查询EventsBus官网里的issue,不难找到开发人员提供的思路:
原因:Check your R8 / ProGuard rules.
来看官方回答网址:
Unable to start activity ComponentInfo m.d.a.g: Subscriber class and its super classes have no public methods with the @Subscribe annotation · Issue #649 · greenrobot/EventBus · GitHub
如何解决呢?我一时也摸不着头脑,经过一阵百度强搜(不是)后获取了答案
在build.gradle里将minifyEnabled true
改为 minifyEnabled false
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
这个解方不适用于我,因为我本来就是minifyEnabled false,写在这里只是防止以后出现问题找不到原因。
4.添加相应的压缩/混淆规则
原因:还是因为R8 或 ProGuard 会混淆方法名称,并可能删除未调用的方法(未使用的代码被删除)。
emm,其实说来也是官网提供的文档介绍有说明,来看网址。
ProGuard - 绿色机器人开源 (greenrobot.org)
解决方法:在proguard-rules.pro里添加如下语句:
-keepattributes *Annotation*
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe<methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# And if you use AsyncExecutor:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
5.将注册的监听事件放到点击接口
因为在此时学习demo里,我图方便将注册事件放在onCreate中的一个按钮监听事件中,但是不知为什么会频频报错。
当然我也怀疑过是生命周期之类的原因,但将其放入之后的生命周期中仍然报错.
百思不得其解之下,将该Activity实现监听接口,放入接口方法中,最后解决改bug。
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
// 注册
if (!EventBus.getDefault().isRegistered(this)){
EventBus.getDefault().register(this);
}
break;
}
}
最后
尽管解决了该bug,但也只知其然,为知其所以然。
因为不知道是什么原因导致我出现此报错,所以后续有时间会接着寻找答案。在此记录,防止忘记。
当然评论区如果有大佬知道,还请不吝赐教。