Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to invoke a method (reflection) with a not generic parameter?
    text
    copied!<p>I have a little problem. I am developing an Android applikation. There you can dynamicly load classes from other applications (packages). First of all, i do not want to "hack" an third-party app, i want to try to build up plugins for my own app. So what do i have?</p> <p>2 Test applications and 1 library which is in both apps included.</p> <p>So the code for app1:</p> <pre><code>package com.ftpsynctest.app1; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import android.app.Activity; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import com.syncoorp.ftpsyncx.commons.SyncFile; import dalvik.system.PathClassLoader; public class App1Activity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); SyncFile f = new SyncFile("bla"); String classname = "com.ftpsynctest.app2.classcall"; String classpath = getApk("com.ftpsynctest.app1") + ":" + getApk("com.ftpsynctest.app2"); PathClassLoader myClassLoader = new dalvik.system.PathClassLoader(classpath, ClassLoader.getSystemClassLoader()); try { Class c = Class.forName(classname, true, myClassLoader); for (Method m : c.getDeclaredMethods()) { System.out.println("Method: " + m.getName()); for (Type t : m.getGenericParameterTypes()) { System.out.println(" - type: " + t.toString()); } m.invoke(c.newInstance(), new Object[] { new com.syncoorp.ftpsyncx.commons.SyncFile("bla") }); break; } } catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} } private String getApk(String packageName) { try { return this.getPackageManager().getApplicationInfo(packageName, 0).sourceDir;} catch (NameNotFoundException e) {e.printStackTrace();} return ""; } } </code></pre> <p>So i want to create the class <strong><em>com.ftpsynctest.app2.classcall</em></strong> and call the method <strong><em>modify</em></strong> with a parameter of type <strong><em>com.syncoorp.ftpsyncx.commons.SyncFile</em></strong>.</p> <p>My app2 code:</p> <pre><code>package com.ftpsynctest.app2; import com.syncoorp.ftpsyncx.commons.SyncFile; public class classcall { public SyncFile modify(SyncFile file) { file.change_date = 123; return file; } } </code></pre> <p>I first installed app2 to <strong>provide</strong> the class to app1. After that succeed i started app1.</p> <p>My Output:</p> <p><strong>01-10 22:21:48.804: INFO/System.out(4681): Method: modify<br> 01-10 22:21:48.809: INFO/System.out(4681): - type: class com.syncoorp.ftpsyncx.commons.SyncFile</strong></p> <p>So for now it looks good. the parameter type of the found method is <strong>com.syncoorp.ftpsyncx.commons.SyncFile</strong> and my provided one is the same.</p> <p>But i get the following error:</p> <pre><code> java.lang.IllegalArgumentException: argument type mismatch at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.ftpsynctest.app1.App1Activity.onCreate(App1Activity.java:44) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) at android.app.ActivityThread.access$1500(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3691) 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:907) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) at dalvik.system.NativeStart.main(Native Method) </code></pre> <p>But why? my output tells me that it is SyncFile and i put SyncFile to the invoke command. Whats the problem there? Can it be that compiling app2 creates a class from SyncFile which is different from the compiled app1 ? if yes, why ? the SyncFile class is the same physical class within my "commons" library which both projects share.</p> <p>Anybody has a solution or answer?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload