Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AndroidAnnotations and EventBus

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.

like image 468
Herrbert74 Avatar asked Jun 22 '15 21:06

Herrbert74


People also ask

What is EventBus used for?

EventBus is an open-source library for Android and Java using the publisher/subscriber pattern for loose coupling. EventBus enables central communication to decoupled classes with just a few lines of code – simplifying the code, removing dependencies, and speeding up app development.

How do I use EventBus on Android?

To tell the EventBus to trigger this method we need to add the @Subscribe annotation to the method. We should unregister and re-register the EventBus in the onStart and onDestroy method on the activity. Now we will call this method on the add item click of second activity.


2 Answers

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.

like image 189
deive Avatar answered Sep 27 '22 21:09

deive


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

like image 26
Alessio Avatar answered Sep 27 '22 19:09

Alessio