How to cast loaded class from external apk into interface class

482 Views Asked by At

//Interface class -> packaged to myinterface.jar

package com.example.my_interface;
import com.example.my_interface.point;

pubic abstract class MyInterface{
    publib Object obj;  
    public abstract Point newPoint(Point p);
}    

//--- and other class ----

package com.example.my_interface.point;
public abstract class Point{
    public int x;
    public int y;   
}

//Project 1 - included myinterface.jar and packaged to classA.apk

package com.testing.classa;
import com.example.my_interface.point;

public class ClsA extends MyInterface{  

    @Override
    public Point newPoint(Point p){
        Point newP;
        newP.x = p.x + 1;
        newP.y = p.y + 1;

        return newP;
    }
}

//Main project // Included myinterface.jar // From this class (ClassB), i want to call "newPoint" method from "ClsA" in classA.apk file.

package com.testing;
import com.example.my_interface.point;

public class ClsB{

    Point p1;
    p1.x = 2;
    p1.y = 3;

    Point newP;

    String apkfilePath = '/data/data/com.testing/files/apps/classA.apk';
    final File optimizedDexOutputPath = cnt.getDir("outdex", Context.MODE_PRIVATE);

    DexClassLoader dLoader = new DexClassLoader(apkfilePath,
                    optimizedDexOutputPath.getAbsolutePath(),
                    null, ClassLoader.getSystemClassLoader().getParent());

    try{
        Class<?> loadedClass = dLoader.loadClass("com.testing.classa.ClsA");
        Object obj = (Object) loadedClass.newInstance();   // (*)

        Method m = loadedClass.getDeclaredMethod("newPoint", Point.class);
        m.setAccessible(true);

        newP = (Point) m.invoke(obj, p1);                   //(**)

    }catch(Exception ex){
        ex.printStackTrace();
    }

    Log.d("NewPoint x",Integer.toString(newP.x));
    Log.d("NewPoint y",Integer.toString(newP.xy));
}

Question 1. At (*): I can not cast "obj" returned after instance to MyInterface class, like:

Object obj = (Object) loadedClass.newInstance();
MyInterface mi = (MyInterface) obj;

-> Error:

Can not cast com.testing.classa.ClsA to com.example.my_interface.MyInterface`

Why not? while in com.testing.classa.ClsA had extends MyInterface ?

Question 2. At (**): ERROR,

java.lang.IllegalArgumentException: argument 1 should have type com.example.my_interface.point, got com.example.my_interface.point

I think in main class had interface myinterface.jar, and on classA.apk had myinterface.jar too, and them can not talk together. What's solution for this problem?

p/s: I searched on google, has someone suggest remove common lib from .apk (here myinterface.jar), but, if removing it that will be can not build because errors.

Help me, thanks.

1

There are 1 best solutions below

2
On BEST ANSWER

You cannot cast as you tried, because you have two interfaces defined. they are called the same, but in different apks. The same applies for Point, thats why you get that second error.

Since you are already using reflection, you could go for full reflection and don't share a jar between the packages at all.

Another solution would be using AIDL, which is an interface definition language for Android