Я пытаюсь создать систему плагинов, которая импортирует фрагменты из других 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 с обеих сторон (плагин и хост).