EventsBus学习问题—— Subscriber class com.eventbustest.xxxActivity$2 and its super classes have ......

文章介绍了在使用EventBus时遇到的一个常见错误,即Subscriber类及其父类找不到@Subscribe注解的方法。作者提供了5种解决方案,包括正确添加注解、在Fragment中正确注册、关闭R8压缩、添加混淆规则以及将注册事件放在适当位置。文章特别提到R8或ProGuard可能混淆方法名并删除未使用代码导致的问题,并给出了相应的混淆规则配置。
摘要由CSDN通过智能技术生成

前言

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,但也只知其然,为知其所以然。

因为不知道是什么原因导致我出现此报错,所以后续有时间会接着寻找答案。在此记录,防止忘记。
当然评论区如果有大佬知道,还请不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薪火_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值