AndroidAnnotations 和 EventBus
AndroidAnnotations and EventBus
我在库中有一个带注释的 Activity,它是同一库中 EventBus 事件的订阅者。它看起来像这样,大大简化了:
@EActivity(resName = "activity_foo")
public class Foo extends Activity {
public void onEvent(BarEvent event){
doSomething();
}
}
它应该按照这个工作:
http://timnew.me/blog/2014/09/14/otto-and-android-annotations-compatibility-issue-analysis/
但实际上 returns 有这个错误:
Unable to start activity ... de.greenrobot.event.EventBusException:
Subscriber class com.foo.bar.activities.Foo_ has no public methods
called onEvent
EventBus 似乎没有在父级中查找 class。我猜每个人都在谈论的@Subscribe 注解只存在于 Guava 和 Otto 中,而没有存在于 EventBus 中。网上没有人在谈论 AA 和 Eventbus 之间的兼容性问题,所以我一定是遗漏了什么。
我怎样才能完成这项工作?
事件总线:2.4
AA: 3.2
编辑:
在 WonderCsabo 的回答后,我将 EventBus 更新到 3.0 beta(包括 Subscribe 注释)并将 AA 更新到 3.3.1,问题消失了,但还有另一个问题:
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.access0(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.access0(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)
而且我注意到这两个问题(缺少 onEvent 和现在的 PostThread 只是发布版本的问题。我使用 ProGuard,但 EventBus 和 AA 有推荐的例外)。
编辑 2:
我加了
-keep class de.greenrobot.** {*;}
它似乎在起作用。
您有三个选择:
- 使用奥托。它也有与 EventBus 相同的问题,但是 AndroidAnnotations 有特定的 Otto integration 解决了这个问题。
- 如果你想坚持使用 EventBus,你可以试试 experimental version,它没有像 2.4.0 那样的问题。它也更好,因为它基于注释而不是方法命名,更不用说可选的 EventBus 注释处理器带来的巨大性能提升。但它仍处于测试阶段。
- 或者您可以使用 EventBus 2.3.0,它没有您在 2.4.0 中遇到的问题。
顺便说一下,你应该更新到最新的 AndroidAnnotations,3.3.1。
我使用 EventBus 注释:
# 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>;
}
请注意,这还可以确保您的方法名称仍然被混淆。
如果有人仍然遇到这个错误,EventBus 3.0 包被重命名(org
而不是 de
,eventbus
而不是 event
),所以正确的混淆器配置是:
## 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);
}
如其 site
中所述
更新
看来这不是正确答案。无论如何都会抛出异常。
原答案
从 EventBus 3 开始,您可以通过调用 throwSubscriberException(false)
.
来禁用订阅者异常
通过在您的应用程序中调用它 class 您可以为您的默认事件总线禁用此异常。
EventBus.builder().throwSubscriberException(false).installDefaultEventBus();
我在库中有一个带注释的 Activity,它是同一库中 EventBus 事件的订阅者。它看起来像这样,大大简化了:
@EActivity(resName = "activity_foo")
public class Foo extends Activity {
public void onEvent(BarEvent event){
doSomething();
}
}
它应该按照这个工作:
http://timnew.me/blog/2014/09/14/otto-and-android-annotations-compatibility-issue-analysis/
但实际上 returns 有这个错误:
Unable to start activity ... de.greenrobot.event.EventBusException: Subscriber class com.foo.bar.activities.Foo_ has no public methods called onEvent
EventBus 似乎没有在父级中查找 class。我猜每个人都在谈论的@Subscribe 注解只存在于 Guava 和 Otto 中,而没有存在于 EventBus 中。网上没有人在谈论 AA 和 Eventbus 之间的兼容性问题,所以我一定是遗漏了什么。
我怎样才能完成这项工作?
事件总线:2.4
AA: 3.2
编辑:
在 WonderCsabo 的回答后,我将 EventBus 更新到 3.0 beta(包括 Subscribe 注释)并将 AA 更新到 3.3.1,问题消失了,但还有另一个问题:
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.access0(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.access0(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)
而且我注意到这两个问题(缺少 onEvent 和现在的 PostThread 只是发布版本的问题。我使用 ProGuard,但 EventBus 和 AA 有推荐的例外)。
编辑 2:
我加了
-keep class de.greenrobot.** {*;}
它似乎在起作用。
您有三个选择:
- 使用奥托。它也有与 EventBus 相同的问题,但是 AndroidAnnotations 有特定的 Otto integration 解决了这个问题。
- 如果你想坚持使用 EventBus,你可以试试 experimental version,它没有像 2.4.0 那样的问题。它也更好,因为它基于注释而不是方法命名,更不用说可选的 EventBus 注释处理器带来的巨大性能提升。但它仍处于测试阶段。
- 或者您可以使用 EventBus 2.3.0,它没有您在 2.4.0 中遇到的问题。
顺便说一下,你应该更新到最新的 AndroidAnnotations,3.3.1。
我使用 EventBus 注释:
# 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>;
}
请注意,这还可以确保您的方法名称仍然被混淆。
如果有人仍然遇到这个错误,EventBus 3.0 包被重命名(org
而不是 de
,eventbus
而不是 event
),所以正确的混淆器配置是:
## 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);
}
如其 site
中所述更新
看来这不是正确答案。无论如何都会抛出异常。
原答案
从 EventBus 3 开始,您可以通过调用 throwSubscriberException(false)
.
通过在您的应用程序中调用它 class 您可以为您的默认事件总线禁用此异常。
EventBus.builder().throwSubscriberException(false).installDefaultEventBus();