AndroidAnnotations and EventBus
Asked Answered
N

4

5

I have an annotated Activity in a library, which is a subscriber to an EventBus event from the same library. It looks something like this, greatly simplified:

@EActivity(resName = "activity_foo")
public class Foo extends Activity {

    public void onEvent(BarEvent event){
        doSomething();
    }
}

It should work according to this:

http://timnew.me/blog/2014/09/14/otto-and-android-annotations-compatibility-issue-analysis/

But in fact it returns with this error:

Unable to start activity ... de.greenrobot.event.EventBusException: Subscriber class com.foo.bar.activities.Foo_ has no public methods called onEvent

It seems EventBus doesn't look in the parent class. I guess the @Subscribe annotation everybody is talking about is only in Guava and Otto, but not in EventBus. Nobody is talking about compatibility problems between AA and Eventbus on the net, so I must be missing something.

How can I make this work?

EventBus: 2.4

AA: 3.2

EDIT:

After WonderCsabo's answer I updated EventBus to 3.0 beta (including Subscribe annotations) and AA to 3.3.1 and the problem is gone, but there is another one:

   java.lang.NoSuchFieldError
            at libcore.reflect.AnnotationAccess.decodeValue(AnnotationAccess.java:688)
            at libcore.reflect.AnnotationAccess.getDefaultValue(AnnotationAccess.java:361)
            at java.lang.reflect.Method.getDefaultValue(Method.java:327)
            at libcore.reflect.AnnotationFactory.getElementsDescription(AnnotationFactory.java:75)
            at libcore.reflect.AnnotationFactory.<init>(AnnotationFactory.java:112)
            at libcore.reflect.AnnotationFactory.createAnnotation(AnnotationFactory.java:94)
            at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:666)
            at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:641)
            at libcore.reflect.AnnotationAccess.getDeclaredAnnotation(AnnotationAccess.java:170)
            at java.lang.reflect.Method.getAnnotation(Method.java:301)
            at de.greenrobot.event.n.b(SourceFile:133)
            at de.greenrobot.event.n.a(SourceFile:79)
            at de.greenrobot.event.c.a(SourceFile:135)
            at com.babestudios.lib.lq.activities.f.onStart(SourceFile:515)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
            at android.app.Activity.performStart(Activity.java:6006)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.NoSuchFieldException: PostThread
            at java.lang.Class.getDeclaredField(Class.java:890)
            at libcore.reflect.AnnotationAccess.decodeValue(AnnotationAccess.java:685)
            at libcore.reflect.AnnotationAccess.getDefaultValue(AnnotationAccess.java:361)
            at java.lang.reflect.Method.getDefaultValue(Method.java:327)
            at libcore.reflect.AnnotationFactory.getElementsDescription(AnnotationFactory.java:75)
            at libcore.reflect.AnnotationFactory.<init>(AnnotationFactory.java:112)
            at libcore.reflect.AnnotationFactory.createAnnotation(AnnotationFactory.java:94)
            at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:666)
            at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:641)
            at libcore.reflect.AnnotationAccess.getDeclaredAnnotation(AnnotationAccess.java:170)
            at java.lang.reflect.Method.getAnnotation(Method.java:301)
            at de.greenrobot.event.n.b(SourceFile:133)
            at de.greenrobot.event.n.a(SourceFile:79)
            at de.greenrobot.event.c.a(SourceFile:135)
            at com.babestudios.lib.lq.activities.f.onStart(SourceFile:515)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
            at android.app.Activity.performStart(Activity.java:6006)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

And I noticed that both problems (the missing onEvent and now the PostThread is only a problem on the release version. I use ProGuard with the recommended exceptions for EventBus and AA).

EDIT 2:

I added

-keep class de.greenrobot.** {*;}

and it seems to be working.

Navarra answered 22/6, 2015 at 21:53 Comment(4)
looks like you try a call Foo_ class instead of Foo class.Embodiment
Yes, that's the point in AA. It's a generated subclass of Foo.Navarra
Did it work for you? I'm tryning to use EventBus 3.0 with AA but it hasn't worked so far... EventBus does not call my subscribed method, although I has posted a message =/Guilder
It still works for me. I use eventbus:3.0.0 and AA:3.3.2. I had to change de.greenrobot:eventbus to org.greenrobot.eventbus.Navarra
E
2

You have three options:

  • Use Otto. It also has the same problem what you faced with EventBus, however AndroidAnnotations has specific Otto integration which solves that problem.
  • If you want to stick with EventBus, you can try out the experimental version, which does not has the issue as 2.4.0. It is also nicer as it is based on annotations instead of the method naming, not speaking of the huge performance boost by the optional EventBus annotation processor. But it is still in beta.
  • Or you can use EventBus 2.3.0, which does not have the problem what you have with 2.4.0.

By the way, you should update to the latest AndroidAnnotations, 3.3.1.

Emersen answered 22/6, 2015 at 22:43 Comment(0)
A
5

I have EventBus Annotations working with:

# Ensure annotations are kept for runtime use.
-keepattributes *Annotation*
# Don't remove any GreenRobot classes
-keep class de.greenrobot.** {*;}
# Don't remove any methods that have the @Subscribe annotation
-keepclassmembers class ** {
    @de.greenrobot.event.Subscribe <methods>;
}

Note that this also ensures that your method names still get obfuscated.

Alsworth answered 22/7, 2015 at 15:26 Comment(0)
T
4

In case someone still faces this error, with EventBus 3.0 the package was renamed (org instead of de, and eventbus instead of event), so the proper proguard configuration is:

## GreenRobot EventBus specific rules ##
# http://greenrobot.org/eventbus/documentation/proguard/

-keepattributes *Annotation*

-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}

-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

as documented in their site

Tegument answered 19/2, 2016 at 8:14 Comment(0)
E
2

You have three options:

  • Use Otto. It also has the same problem what you faced with EventBus, however AndroidAnnotations has specific Otto integration which solves that problem.
  • If you want to stick with EventBus, you can try out the experimental version, which does not has the issue as 2.4.0. It is also nicer as it is based on annotations instead of the method naming, not speaking of the huge performance boost by the optional EventBus annotation processor. But it is still in beta.
  • Or you can use EventBus 2.3.0, which does not have the problem what you have with 2.4.0.

By the way, you should update to the latest AndroidAnnotations, 3.3.1.

Emersen answered 22/6, 2015 at 22:43 Comment(0)
T
0

UPDATE

It seems this is not the right answer. The exception is thrown anyway.

Original Answer

As of EventBus 3 you can disable the subscriber exception by calling throwSubscriberException(false).

By calling this in your application class you can disable this exception for your default event bus.

EventBus.builder().throwSubscriberException(false).installDefaultEventBus();
Tass answered 1/3, 2016 at 0:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.