Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Android 2.3: Classes generated with @EActivity don't contain method getDeclaredMethods()  #747

Description

@AnnKrajnik

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:

@EActivity(R.layout.activity_test)
public class CompanyActivity extends NavigationActivity{
...
@AfterViews
void init(){
Method[] ms = this.getClass().getDeclaredMethods();
   ...
}
}

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.

Activity

  1. DayS commented on Sep 30, 2013

    @DayS
    Contributor

    Two things here :

    1. the method getDeclaredMethods is part of the JDK and is provided by Class class. It's not an AA issue;
    2. 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.

  2. AnnKrajnik commented on Sep 30, 2013

    @AnnKrajnik
    Author

    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.

  3. AnnKrajnik commented on Oct 1, 2013

    @AnnKrajnik
    Author

    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.

  4. DayS commented on Oct 1, 2013

    @DayS
    Contributor

    Strange indeed... I suspect this was a side-effect of an AA bug. But I can't tell you which one.

  5. DayS commented on Oct 4, 2013

    @DayS
    Contributor

    I'm closing this issue. Please re-open if you're stuck again with this.

  6. tpettersen commented on Oct 21, 2013

    @tpettersen

    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? :)

  7. DayS commented on Oct 21, 2013

    @DayS
    Contributor

    Damn.. I'll dig on this one this week.

  8. reopened this on Oct 22, 2013
  9. DayS commented on Oct 22, 2013

    @DayS
    Contributor

    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 new IntentBuilder constructors for Activity subclass :

    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 Fragment has been introduced since Android 3.0, Dalvik will crash on intent(android.app.Fragment) on Android 2.3 and throw a NoSuchMethodException.

    So, I think we could just check the AndroidManifest and generate intent(android.app.Fragment) only if minSdkVersion >= 11.
    What do you think ? @JoanZapata @jeremiemartinez @yDelouis do you have other ideas ?

  10. shirish87 commented on Oct 22, 2013

    @shirish87

    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. :)

  11. tbruyelle commented on Oct 23, 2013

    @tbruyelle
    Contributor

    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 the onActivittyResult() method from the fragment to the activity.

  12. DayS commented on Oct 23, 2013

    @DayS
    Contributor

    Ok. I'm working on a patch then

  13. ghost assigned on Oct 23, 2013
  14. shirish87 commented on Oct 23, 2013

    @shirish87

    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 :)

  15. DayS commented on Oct 23, 2013

    @DayS
    Contributor

    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 :)

  16. shirish87 commented on Oct 23, 2013

    @shirish87

    Awesome! Thanks! :)

  17. DayS commented on Oct 23, 2013

    @DayS
    Contributor

    It should be fixed now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions