2

I am having a strange issue where I am trying to dynamically load an interface and pass it to a dynamically loaded class method as a parameter, this is on android.

MyClass.java

public class MyClass{
    public interface MyInterface {
        void onSomeAction(int i,String s);
    }

    public static void setDelegate(MyInterface mInterface){
        myInterface = mInterface;
    }
    //rest of class
}

I am trying to access both MyClass and MyInterface dynamically below (in another java file).

String packageName = "com.example.dynamicinterface";
PackageManager packageManager = getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
DexFile df = new DexFile(appInfo.sourceDir);
ClassLoader cl = getClassLoader();
Class myClass = df.loadClass("com.example.dynamicinterface.MyClass",cl);
Class<?> myInterface = df.loadClass("com.example.dynamicinterface.MyClass$MyInterface",cl);
Method method = myClass.getMethod("setDelegate", myInterface);
method.invoke(null,myInterface);

The last line

method.invoke(null,myInterface);

throws the following exception

java.lang.IllegalArgumentException: method com.example.dynamicinterface.MyClass.setDelegate argument 1 has type com.example.dynamicinterface.MyClass$MyInterface, got java.lang.Class<com.example.dynamicinterface.MyClass$MyInterface>

I am stumped. I have looked at several examples and all seems to be doing the same thing I'm doing. Any ideas? Thanks in advance

user3689913
  • 382
  • 4
  • 10
  • 3
    You are trying to pass a `Class` object where a `MyInterface` instance is expected. Of course, that’s rejected. You have to create an appropriate object, but interfaces are always abstract, so you have to create an instance of a class implementing the interface. – Holger Dec 16 '21 at 09:14

1 Answers1

1

Big thanks to @Holger, I was able to solve my problem using the Proxy class. Have a look at Java Reflection: Create an implementing class. I implemented a proxy instance and passed that as the 2nd parameter to the invoke call.

Class<?> myInterface = df.loadClass("com.example.dynamicinterface.MyClass$MyInterface",cl);

Object proxy = Proxy.newProxyInstance(myInterface.getClassLoader(),
                    new Class[] { myInterface },
                    new MyInvocationHandler());

 myClass.getMethod("setDelegate", myInterface).invoke(null,proxy);    
user3689913
  • 382
  • 4
  • 10