【问题标题】:Cast object to interface when created via reflection通过反射创建时将对象转换为接口
【发布时间】:2010-06-03 20:32:25
【问题描述】:

我在 Android 中尝试了一些东西,但在尝试将另一个 .apk 中的类投射到我的界面时遇到了困难。我在实现该接口的其他 .apks 中有接口和各种类。我使用 PackageManager 的查询方法找到其他类,并使用 Application#createPackageContext() 来获取该上下文的类加载器。然后我加载该类,创建一个新实例并尝试将其转换为我的接口,我知道它肯定实现了。

当我尝试强制转换时,它会抛出一个类强制转换异常。我尝试了各种方法,例如先加载界面,使用 Class#asSubclass 等,但都不起作用。 Class#getInterfaces() 显示接口已实现。我的代码如下:

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();
    }
}

【问题讨论】:

    标签: java android classloader casting


    【解决方案1】:

    我没有做过任何 Android 开发,所以我不确定它的类加载器的细微差别,但在一般 Java 编程中,由不同类加载器加载的两个类是不一样的……即使它们是从同一个类“文件”。

    因此,如果您在“您的”类加载器中加载接口 X,然后从“外部”类加载器中获取一个似乎实现类 X 的对象,则进行强制转换到“你的”X 会失败。

    要使其工作,X 必须从一个类加载器加载,该类加载器是其他两个加载器的公共父级。

    【讨论】:

    • 啊,这就解释了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-01-18
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 2015-01-22
    相关资源
    最近更新 更多