Приведение объекта к интерфейсу при создании с помощью отражения - PullRequest
3 голосов
/ 04 июня 2010

Я пробую кое-что в Android и застрял при попытке привести класс в другом .apk к моему интерфейсу. У меня есть интерфейс и различные классы в других .apks, которые реализуют этот интерфейс. Я нахожу другие классы, используя методы запросов PackageManager и использую Application # createPackageContext (), чтобы получить загрузчик классов для этого контекста. Затем я загружаю класс, создаю новый экземпляр и пытаюсь привести его к моему интерфейсу, который, я знаю, он определенно реализует.

Когда я пытаюсь разыграть, он генерирует исключение приведения класса. Я пробовал разные вещи, такие как загрузка интерфейса в первую очередь, использование Class # asSubclass и т. Д., Но ни одна из них не работает. Класс # 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();
    }
}

1 Ответ

3 голосов
/ 04 июня 2010

Я не занимался разработкой для Android, поэтому не уверен в нюансах его загрузчиков классов, но в целом в Java-программировании два класса, загружаемых разными загрузчиками классов, не одинаковы & hellip; даже если они загружены из одного и того же класса «файл».

Итак, если вы загружаете интерфейс X в «ваш» загрузчик классов, а затем получаете объект, который появляется для реализации класса X из «чужого» загрузчика классов, приведение "ваш" X потерпит неудачу.

Чтобы это работало, X должен быть загружен из загрузчика классов, который является общим родителем для двух других загрузчиков.

...