开发者

Cast object to interface when created via reflection

I'm trying some stuff out in Andr开发者_C百科oid and I'm stuck at when trying to cast a class in another .apk to my interface. I have the interface and various classes in other .apks that implement that interface. I find the other classes using PackageManager's query methods and use Application#createPackageContext() to get the classloader for that context. I then load the class, create a new instance and try to cast it to my interface, which I know it definitely implements.

When I try to cast, it throws a class cast exception. I tried various things like loading the interface first, using Class#asSubclass, etc, none of which work. Class#getInterfaces() shows the interface is implemented. My code is below:

PackageManager pm = getPackageManager();
List<ResolveInfo> lr = pm.queryIntentServices(new Intent("com.example.some.action"), 0);
ArrayList<MyInterface> list = new ArrayList<MyInterface>();

for (ResolveInfo r : lr) {
    try {
        Context c = getApplication().createPackageContext(r.serviceInfo.packageName, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
        ClassLoader cl = c.getClassLoader();
        String className = r.serviceInfo.name;
        if (className != null) {
            try {
                Class<?> cls = cl.loadClass(className);
                Object o = cls.newInstance();
                if (o instanceof MyInterface) { //fails
                    list.add((MyInterface) o);
                }

            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } // some exceptions removed for readability
        }
    } catch (NameNotFoundException e1) {
        e1.printStackTrace();
    }
}


I haven't done any Android development, so I'm not sure of the nuances of its class loaders, but in general Java programming, two classes loaded by different class loaders are not the same… even if they are loaded from the same class "file".

So, if you load the interface X in "your" class loader, and then get an object that appears to implement class X from a "foreign" class loader, a cast to "your" X will fail.

To make it work, X has to be loaded from a class loader that is a common parent to the other two loaders.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜