Класс разрешен неожиданным DEX, как избежать дублирования импорта

Я пытаюсь создать систему плагинов, которая импортирует фрагменты из других apks, как описано здесь.

Эклипс продолжает говорить мне:

12-01 15:17:18.609: W/dalvikvm(23425): класс разрешен неожиданным DEX: Lde/anthropotec/activityapp/firstplugin/UI;(0x42901520):0x57d93000 ref [Lde/anthropotec/activityapp/api/PluginAPI;] Lde/антропотек/деятельностьприложение/апи/PluginAPI; (0x428eb2b8): 0x527e1000

(Lde/anthropotec/activityapp/firstplugin/UI; использовал другой Lde/anthropotec/activityapp/api/PluginAPI; во время предварительной проверки)

Что неудивительно, так как я импортирую свою библиотеку PluginAPI как в хост, так и в плагин. Насколько я понимаю, Eclipse боится, что эти библиотеки не идентичны. Есть ли способ сказать Eclipse не импортировать библиотеку, если она уже есть в другом apk? Или есть другой способ обойти это. Пожалуйста, сообщите мне, если вам нужна дополнительная информация. Вот мой источник:

Гостья:

package de.anthropotec.activityapp.host;

import java.io.File;

import dalvik.system.DexClassLoader;
import de.anthropotec.activityapp.api.PluginAPI;
import de.anthropotec.activtiyapp.host.R;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;

public class MainActivtiy extends Activity{
    
    @Override
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    
    setContentView(R.layout.main);
    
    try {
        Class<?> requiredClass = null;
        final ApplicationInfo info = getPackageManager().getApplicationInfo("de.anthropotec.activityapp.firstplugin",0);
        final String apkPath = info.sourceDir;
        final File dexTemp = getDir("temp_folder", 0);
        final String fullName = "de.anthropotec.activityapp.firstplugin.UI";
        boolean isLoaded = true;

        // Check if class loaded
        try {
            requiredClass = Class.forName(fullName);
        } catch(ClassNotFoundException e) {
            isLoaded = false;
        }

        if (!isLoaded) {
            final DexClassLoader classLoader = new DexClassLoader(apkPath, dexTemp.getAbsolutePath(), null, getApplicationContext().getClassLoader());
            requiredClass = classLoader.loadClass(fullName);
        }

        if (null != requiredClass) {
            // Try to cast to required interface to ensure that it's can be cast
            final PluginAPI holder = PluginAPI.class.cast(requiredClass.newInstance());

            if (null != holder) {
                final Fragment fragment = holder.getFragment();

                if (null != fragment) {
                    final FragmentTransaction trans = getFragmentManager().beginTransaction();

                    trans.add(R.id.pluginPlace, fragment, "MyFragment").commit();
                }
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    }
}  

Плагинапи:

package de.anthropotec.activityapp.api;

import android.app.Fragment;


public interface PluginAPI {

    public Fragment getFragment();
}

И сам плагин-фрагмент:

package de.anthropotec.activityapp.firstplugin;

import de.anthropotec.activityapp.api.PluginAPI;
import android.app.Fragment;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.view.View;
import android.view.LayoutInflater;
import android.view.ViewGroup;

public class UI extends Fragment implements PluginAPI{

     @Override
        public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
            // Note that loading of resources is not the same as usual, because it loaded actually from another apk
            final XmlResourceParser parser = container.getContext().getPackageManager().getXml("de.anthropotec.testplugin", R.layout.ui, null);
            return inflater.inflate(parser, container, false);
        }

        @Override
        public Fragment getFragment() {
            return this;
        }
    
}

Каждый из вышеперечисленных как собственный проект (PluginAPI как библиотека). Вопрос не совсем новый (например, здесь), но уже данные ответы советуют удалить импорт, что в моем случае это не вариант, так как мне нужен API с обеих сторон (плагин и хост).


person Kevin Gebhardt    schedule 01.12.2014    source источник


Ответы (1)


Ах, иногда это так очевидно. Просто импортируйте библиотеку как внешнюю библиотеку в «Свойства» -> «Путь сборки Java» -> добавьте внешнюю банку для плагина, и все будет работать нормально. Гнарф!

person Kevin Gebhardt    schedule 01.12.2014