You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 30, 2019. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 30, 2019. It is now read-only.
NoSuchMethodException when registering class instances on Android 2.2 & 2.3.7 #37
Each and every time I try to register a class instance as a listener on OS versions older than Honeycomb, my app throws a NoSuchMethodException. I know that on the site it's stated that the library "is compatible with all versions of Android and has no minimum SDK requirement.", but this probably has to do something with that, since it runs perfectly on Honeycomb, ICS & Jelly Bean.
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to resume activity {com.app/com.uilibrary.HomeActivity}: java.lang.NoSuchMethodException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2241)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2256)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1789)
at android.app.ActivityThread.access$1500(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)
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:116)
at com.squareup.otto.HandlerFinder$1.findAllProducers(HandlerFinder.java:33)
at com.squareup.otto.Bus.register(Bus.java:187)
at com.uilibrary.HomeActivity.onResume(HomeActivity.java:218)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
at android.app.Activity.performResume(Activity.java:3832)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2231)
... 12 more
Er, this would indicate a seriously broken version of Dalvik since Class#getDeclaredMethods() has been available since API 1. Does this happen on emulators, phones, or both? Is the device running a custom ROM from an OEM (e.g., HTC Sense, MotoBlur, TouchWiz, etc.)?
1st device: LG P500 running Android OS 2.2 (this should be stock Android)
2nd device: Orange Boston - Gigabyte G1305 running CyanogenMod 7.2 (Android 2.3.7)
Since they are very different, the problem should be something else. Note that I'm using your ActionBarSherlock library, but that shouldn't be an issue.
Edit 1: just checked it on a Motorola Milestone running 2.2.1 ... same problem
Edit 2: The HomeActivity extends SherlockFragmentActivity (maybe there's something wrong when extending onResume?)
I have no listeners in xml files, and also checked the project with Lint, but there's no API call that should have any backwards compatibility problem. Any other ideas?
Edit: I red swankjesse's post over and over, and finally managed to solve the problem. Turns out I had a widget available from API level 11 in my code. Event if it was only declared, not used within the code where the app was running on older Android versions, the app was crashing. Don't know why exactly the exception was thrown pointing to this library, but probably because of the process described by swankjesse in the blog post above.
Thanks for the support, and sorry because of the false alarm.
Keep up the good work!
This should be re-opened. Otto uses reflection to look for producers. If a method class takes a parameter that didn't exist on the version being tested, it'll fail.
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 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)
For example, assuming the containing class contains a register call, this method existing will cause Otto to fail on 2.3 (without being called).
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public JsonReader testMethod(JsonReader test) {
return null;
}
@JakeWharton Agreed that a fundamental re-write would resolve this, but short of that, documenting this gotcha is probably important. Aside from that, I'd experiment with catching the exception and continuing. A developer shouldn't have a method that would cause this behavior that would also be subscribing or producing on that version of Android.
The workaround we're using for now is encouraging the use of inner classes and interface implementations to subscribe and produce, thus preventing the parent from being iterated on and containing the event bus logic to a guaranteed area.
Something like this in a base class:
public interface EventBusMethods { }
protected abstract Bus getEventBus();
protected abstract EventBusMethods getEventBusMethods();
public BaseClass() {
getEventBus().register(getEventBusMethods());
}
Activity
JakeWharton commentedon Nov 12, 2012
Er, this would indicate a seriously broken version of Dalvik since
Class#getDeclaredMethods()has been available since API 1. Does this happen on emulators, phones, or both? Is the device running a custom ROM from an OEM (e.g., HTC Sense, MotoBlur, TouchWiz, etc.)?klevi commentedon Nov 12, 2012
1st device: LG P500 running Android OS 2.2 (this should be stock Android)
2nd device: Orange Boston - Gigabyte G1305 running CyanogenMod 7.2 (Android 2.3.7)
Since they are very different, the problem should be something else. Note that I'm using your ActionBarSherlock library, but that shouldn't be an issue.
Edit 1: just checked it on a Motorola Milestone running 2.2.1 ... same problem
Edit 2: The HomeActivity extends SherlockFragmentActivity (maybe there's something wrong when extending onResume?)
swankjesse commentedon Nov 12, 2012
This looks a lot like the cunning android bug I encountered in August.
klevi commentedon Nov 13, 2012
I have no listeners in xml files, and also checked the project with Lint, but there's no API call that should have any backwards compatibility problem. Any other ideas?
Edit: I red swankjesse's post over and over, and finally managed to solve the problem. Turns out I had a widget available from API level 11 in my code. Event if it was only declared, not used within the code where the app was running on older Android versions, the app was crashing. Don't know why exactly the exception was thrown pointing to this library, but probably because of the process described by swankjesse in the blog post above.
Thanks for the support, and sorry because of the false alarm.
Keep up the good work!
tyvsmith commentedon Feb 18, 2014
This should be re-opened. Otto uses reflection to look for producers. If a method class takes a parameter that didn't exist on the version being tested, it'll fail.
For example, assuming the containing class contains a register call, this method existing will cause Otto to fail on 2.3 (without being called).
JakeWharton commentedon Feb 18, 2014
@tyvsmith What would you expect the library to do in that case? Without a fundamental re-write we're forced to use reflection.
tyvsmith commentedon Feb 18, 2014
@JakeWharton Agreed that a fundamental re-write would resolve this, but short of that, documenting this gotcha is probably important. Aside from that, I'd experiment with catching the exception and continuing. A developer shouldn't have a method that would cause this behavior that would also be subscribing or producing on that version of Android.
tyvsmith commentedon Feb 19, 2014
The workaround we're using for now is encouraging the use of inner classes and interface implementations to subscribe and produce, thus preventing the parent from being iterated on and containing the event bus logic to a guaranteed area.
Something like this in a base class:
Get selected text from the WebView.