Repository navigation
Android 2.3: Classes generated with @EActivity don't contain method getDeclaredMethods() #747
Description
Activity
Two things here :
- the method
getDeclaredMethodsis part of the JDK and is provided byClassclass. It's not an AA issue; - reflection may be used on Android 4.0. But prior than this version, reflection was badly implemented on Dalvik. It causes such bad performances issues that you shouldn't use it on these versions.
Also, you should use Github flavored markdown to format code in github issues.
- the method
Oh, sorry, I promise to use code formating in future)
Thanks for your answer. The Dalvik error really may be the cause of problem. But crashed only on activities - it's very strange and I thought that the cause could be a bad generation of an activity's class.
Interesting fact: I began to use the version of AA 3.0-SNAPSHOT by 20130903 (I get it from my local repository) and my application works perfect. But crashes if I use later versions. Crashes began 20130923.
Strange indeed... I suspect this was a side-effect of an AA bug. But I can't tell you which one.
I'm closing this issue. Please re-open if you're stuck again with this.
Hi!
I got the same issue. The error occurs only on Android 2.3 and was working until recent 3.0-snapshot releases, as mentioned above by @AnnKrajnik.
My problem is exactly the same, but I'm not using reflection manually in any way. In my Activity annotated with @EActivity, in onResume(), i'm using Otto to register my class on Otto's bus. The bug is easily reproducable:
@EActivity public class SampleActivity extends SherlockActivity { @Override protected void onResume() { super.onResume(); // Register on Otto bus BusProvider.getInstance().register(this); } }
Otto uses getDeclaredMethods(), which fails with the following stacktrace:
Caused by: java.lang.NoSuchMethodException at java.lang.Class.getDeclaredMethods(Native Method) at java.lang.ClassCache.getDeclaredMethods(ClassCache.java:140) at java.lang.Class.getDeclaredMethods(Class.java:757) at com.squareup.otto.AnnotatedHandlerFinder.loadAnnotatedMethods(AnnotatedHandlerFinder.java:52) at com.squareup.otto.AnnotatedHandlerFinder.findAllProducers(AnnotatedHandlerFinder.java:119) at com.squareup.otto.HandlerFinder$1.findAllProducers(HandlerFinder.java:33) at com.squareup.otto.Bus.register(Bus.java:187)Basically, I think the support for Otto in AndroidAnnotations is broken. I know of course that I'm running a snapshot, but I really would like to have both Otto and AndroidAnnotations at once, since they help me speed up the development and decouple my code.
Any ideas if it's my code or yours? :)
Damn.. I'll dig on this one this week.
I did some tests and research and it's definitely because of a reflection issue on Android 2.3. This comment on Otto's issue help me find what happens here.
Since commit 0b88c44, AA will generate these newIntentBuilderconstructors forActivitysubclass :public static MainActivity_.IntentBuilder_ intent(android.app.Fragment fragment) { return new MainActivity_.IntentBuilder_(fragment); } public static MainActivity_.IntentBuilder_ intent(android.support.v4.app.Fragment fragment) { return new MainActivity_.IntentBuilder_(fragment); }
Otto calls
java.lang.Class.getDeclaredMethods()during registration, which will load all methods of generated class, including these two constructors.- If the project configuration (android-support added in classpath) is fine
intent(android.support.v4.app.Fragment)should work. - But because
Fragmenthas been introduced since Android 3.0, Dalvik will crash onintent(android.app.Fragment)on Android 2.3 and throw aNoSuchMethodException.
So, I think we could just check the AndroidManifest and generate
intent(android.app.Fragment)only ifminSdkVersion >= 11.
What do you think ? @JoanZapata @jeremiemartinez @yDelouis do you have other ideas ?- If the project configuration (android-support added in classpath) is fine
Nice catch! 👍
I'm facing the same issue with AA-3.0-snapshot and EventBus on Android 2.3. Scratching my head wondering how this basic method call could throw an exception. :)Oups sorry for this sneaky bug... (I'm the author of 0b88c44)
So, I think we could just check the AndroidManifest and generate intent(android.app.Fragment) only if minSdkVersion >= 11.
Agree, because anyway this method can be replaced by
intent(Activity activity), the user just has to move theonActivittyResult()method from the fragment to the activity.Ok. I'm working on a patch then
I have a hurriedly coded fix that seems to be working, but the test case depending on intent(android.app.Fragment) fails - for obvious reasons. :(
Hope this helps :)I already fixed this on my local repo. Just working on some unit tests and it should be available this evening :)
EDIT: It seems we had nearly the same fix :)
Awesome! Thanks! :)
It should be fixed now
I use Android Studio and Gradle to build my project, version of annotations - 3.0-SNAPSHOT. When I try to call method getDeclaredMethods() for my activity's class then it throw NoSuchMethod exception on devices(and emulators) with Android 2.3.x. On devices with 4.0 and later all work good.
Code sample:
Error stack trace:
Caused by: java.lang.NoSuchMethodException
at java.lang.Class.getDeclaredMethods(Native Method)
at java.lang.ClassCache.getDeclaredMethods(ClassCache.java:140)
at java.lang.Class.getDeclaredMethods(Class.java:757)
at my.app.test.activity.TestActivity.init(TestActivity.java:25)
at my.app.test.activity.TestActivity_.onViewChanged(TestActivity_.java:43)
When I call this method for another generated classes - for example, generated with @efragment or with @eviewgroup - app doesn't crash.