My problem is simple. So simple I can’t seem to figure it out. I am passing a qualified class name to a BroadcastReceiver as a String in an Intent.
The goal is to instantiate an object from the class name using reflection, and call a method which we know exists, because it implements a proprietary interface. I am even checking it against getDeclaredMethods() which says its there, but when I try to invoke that method, it throws a java.lang.NoSuchMethodException.
String myClass = intent.getStringExtra("name");
Class<?> c = Class.forName(myClass);
Object object = c.newInstance();
// Get the files from the interface
Method ms[] = c.getDeclaredMethods();
for (Method m1 : ms) {
Log.i("METHOD", "METHODS " + m1.getName());
}
Method m = c.getDeclaredMethod("getStrings", (Class<?>) null);
String[] someStrings = (String[]) m.invoke(object, (Object[]) null);
m = c.getDeclaredMethod("getThings", (Class<?>) null);
Thing[] things = (Thing[]) m.invoke(object, (Object[]) null);
Here is the LogCat output:
08-30 23:37:36.150: INFO/METHOD(2336): METHODS getStrings
08-30 23:37:36.150: INFO/METHOD(2336): METHODS getThings
08-30 23:37:36.150: WARN/System.err(2336): java.lang.NoSuchMethodException: getStrings
08-30 23:37:36.150: WARN/System.err(2336): at java.lang.ClassCache.findMethodByName(ClassCache.java:247)
08-30 23:37:36.150: WARN/System.err(2336): at java.lang.Class.getDeclaredMethod(Class.java:731)
08-30 23:37:36.150: WARN/System.err(2336): at com.app.MyBroadcastReceiver.onReceive(MyBroadcastReceiver.java:45)
08-30 23:37:36.150: WARN/System.err(2336): at android.app.ActivityThread.handleReceiver(ActivityThread.java:1794)
08-30 23:37:36.150: WARN/System.err(2336): at android.app.ActivityThread.access$2400(ActivityThread.java:117)
08-30 23:37:36.150: WARN/System.err(2336): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:981)
08-30 23:37:36.150: WARN/System.err(2336): at android.os.Handler.dispatchMessage(Handler.java:99)
08-30 23:37:36.160: WARN/System.err(2336): at android.os.Looper.loop(Looper.java:130)
08-30 23:37:36.160: WARN/System.err(2336): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-30 23:37:36.160: WARN/System.err(2336): at java.lang.reflect.Method.invokeNative(Native Method)
08-30 23:37:36.160: WARN/System.err(2336): at java.lang.reflect.Method.invoke(Method.java:507)
08-30 23:37:36.160: WARN/System.err(2336): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-30 23:37:36.160: WARN/System.err(2336): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-30 23:37:36.160: WARN/System.err(2336): at dalvik.system.NativeStart.main(Native Method)
Is there something I am missing here?
Edit: Added the code to the class
public class MyClass implements MyInterface {
@Override
public String[] getStrings() {
// Stub
return new String[2];
}
@Override
public Thing[] getThings() {
// Stub
return new Thing[2];
}
}
Note: The BroadcastReceiver and the Class are in different projects.
getDeclaredMethod requires you give the right parameters. If there are no parameters, then instead of passing “null”, you need to pass absolutely nothing.
For example, here is a code snippet for hashCode, which takes no arguments
it will print out “test”, then throw a MethodNotFound exception as hashCode takes no arguments. If you want to get the argument types as well as the name, execute the getParameterTypes on the method object