Подтвердить что ты не робот

Активность Android в Eclipse/ADT с зависимостями проекта (с ошибкой XY)

Я старался, чтобы игровой проект был совершенно независимым от платформы, поэтому я разделил его на три проекта с низкого уровня на верхний специфический для Android уровень: двигатель, игра, игра для Android.

Причастными классами/интерфейсами в ошибке являются:

  • (низкоуровневый) проект engine определяет этот интерфейс:

    com.myteam.engine.IGame
    
  • (средний уровень) независимый от платформы игровой проект определяет эти классы:

    com.myteam.myproject.Game
    com.myteam.myproject.MyProject (derived from com.myteam.myproject.Game)
    
  • (верхний уровень) проект android реализует активность и т.д.:

    com.myteam.myproject.android.MyAndroidActivity (using com.myteam.myproject.MyProject)
    

Все компилируется и отлично работает под Windows (с другим проектом Windows на уровне 3 с использованием первых двух).

Но при работе с ADT он не работает во время выполнения, когда начинается Activity. Приложение Android в основном просто отображает стек вызовов с исключением "NoClassDefFoundError com.myteam.myproject.MyProject".

Исключение похоже на его суперкласс (или интерфейс суперкласса) при загрузке/разрешении, поскольку вывод LogCat показывает:

12-20 19:51:51.897: D/ddm-heap(218): Got feature list request
12-20 19:51:52.207: I/dalvikvm(218): Failed resolving Lcom/myteam/myproject/Game; interface 18 'Lcom/myteam/engine/IGame;'
12-20 19:51:52.217: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/Game;' failed
12-20 19:51:52.227: W/dalvikvm(218): Unable to resolve superclass of Lcom/myteam/myproject/MyProject; (52)
12-20 19:51:52.227: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/MyProject;' failed
12-20 19:51:52.227: E/dalvikvm(218): Could not find class 'com.myteam.myproject.MyProject', referenced from method com.myteam.myproject.android.MyAndroidActivity.onCreate
12-20 19:51:52.227: W/dalvikvm(218): VFY: unable to resolve new-instance 54 (Lcom/myteam/myproject/MyProject;) in Lcom/myteam/myproject/android/Youcode_AndroidActivity;
12-20 19:51:52.227: D/dalvikvm(218): VFY: replacing opcode 0x22 at 0x0008
12-20 19:51:52.227: D/dalvikvm(218): Making a copy of Lcom/myteam/myproject/android/Youcode_AndroidActivity;.onCreate code (88 bytes)

Я попытался добавить два первых проекта в настройках проекта "Создание пути/порядок и экспорт" Eclipse проекта Android, как описано в других сообщениях и форумах, но это ничего не меняет.

Моя догадка заключается в том, что для параметров манифеста или проекта необходимо другое упоминание о зависимости пакета/класса для упаковки apk или времени выполнения. Любые идеи?

4b9b3361

Ответ 1

У меня есть трехуровневое приложение для Android/Java, почти так же, как вы:

  • Проект только для Java для низкоуровневой сетевой коммуникации
  • Проект только для Java для абстрагирования низкоуровневых функций проекта.
  • Android-приложение

Каждая вещь выше - отдельный проект Eclipse, содержащийся в одной рабочей области.

Вот что вам нужно сделать:

  • В свойствах проекта приложения- > Java Build Path- > Projects, добавьте проекты только для Java.
  • В свойствах проекта приложения- > Java Build Path- > Order and Export, проверьте проекты только для Java (которые маркируют их для экспорта)

Теперь ваше приложение должно создавать и запускать без исключений NoClassDefFoundError или VFY, таких как:

03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.160: I/dalvikvm(420): Failed resolving Lcom/demo/log/AndroidLogWrapper; interface 253 'Lcommon/Logger/LogWrapper;'
03-27 21:10:17.160: W/dalvikvm(420): Link of class 'Lcom/demo/log/AndroidLogWrapper;' failed
03-27 21:10:17.160: E/dalvikvm(420): Could not find class 'com.demo.log.AndroidLogWrapper', referenced from method com.demo.Application.onCreate
03-27 21:10:17.160: W/dalvikvm(420): VFY: unable to resolve new-instance 218 (Lcom/demo/log/AndroidLogWrapper;) in Lcom/demo/Application;
03-27 21:10:17.170: D/dalvikvm(420): VFY: replacing opcode 0x22 at 0x0003
03-27 21:10:17.170: D/dalvikvm(420): VFY: dead code 0x0005-003c in Lcom/demo/Application;.onCreate ()V
03-27 21:10:17.170: D/AndroidRuntime(420): Shutting down VM
03-27 21:10:17.170: W/dalvikvm(420): threadid=1: thread exiting with uncaught exception (group=0x40015560)
03-27 21:10:17.180: E/AndroidRuntime(420): FATAL EXCEPTION: main
03-27 21:10:17.180: E/AndroidRuntime(420): java.lang.NoClassDefFoundError: com.demo.log.AndroidLogWrapper

Кстати, перед ADT r17 вам нужно было сделать только шаг 1 выше (добавить проекты только для Java). Но начиная с r17 вам также нужно сделать шаг 2 (отметьте проекты только для Java для экспорта).

Ответ 2

Добавьте название ваших зависимых проектов в файл .claspath вашего проекта Android. например:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="src" path="gen"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject1"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject2"/>
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
    <classpathentry kind="output" path="bin"/>
</classpath>

Ответ 3

Я пытаюсь найти простое решение для этого давным-давно, насколько я могу судить, единственный способ заставить ADT экспортировать final apk с зависимыми библиотечными классами явно добавить все ваши внешние lib.jar( созданный из ваших других проектов) в ваш путь создания проекта Android.

Текущая версия плагина Eclipse ADT имеет очень негибкий предопределенный жизненный цикл сборки (в частности, на этапе dexing), по-видимому, он не поддерживает группировку проектов, отличную от трех типов Android Project (классика, библиотека и тест). Другими словами, ADT не знает, как создать проект Android с помощью обычного java-зависимого проекта в пути сборки и автоматически добавить lib.jar, сгенерированный зависимым проектом, в ваш основной путь создания проекта (даже если вы добавите их в Order и Export), если вы явно не добавите в него внешний lib.jar. Предположим, вы добавили C:\workspace\game\target\game.jar и C:\workspace\engine\target\engine.jar в свой путь сборки проекта для Android, команда для создания вашего файла dex должна быть примерно такой:

java [-Xmx1024M, -jar, C:\android-sdk-r16\platform-tools\lib\dx.jar, --dex, --output=C:\workspace\android-game\target\classes.dex, C:\workspace\android-game\target\classes, C:\workspace\game\target\game.jar, C:\workspace\engine\target\engine.jar]

Если вы планируете использовать некоторые внешние средства сборки для управления жизненным циклом проекта, я знаю, что Maven обеспечивает более гибкую конфигурацию в течение жизненного цикла Android. Он поддерживает многомодульный проект (группирование проектов) и может корректно обрабатывать регулярную зависимость проекта Java.

Мои знания основаны на Eclipse, с нетерпением ожидаем услышать какие-то шумы от источника Android или другого сложного пользователя IDE.

Обновление с ADT 17.0.0:

Последняя версия SDK r17 с ADT 17.0.0 утверждает, что теперь корректно обрабатывает эти варианты использования:

Изменения в Eclipse

Контейнер динамических классов классов, называемый "Библиотечные проекты", был переименован в "Android Dependencies", поскольку теперь он содержит больше, чем только проекты библиотеки.

Теперь контейнер будет также заполнен проектами только для Java, на которые ссылаются проекты библиотек. Если эти Java-проекты также ссылаются на другие Java-проекты и/или файлы jar, они будут добавляться автоматически (также поддерживаются файлы jar, на которые ссылаются пользовательские библиотеки).

Важно: это происходит только в том случае, если ссылки заданы для экспорта в проект ссылки. Обратите внимание, что это не значение по умолчанию при добавлении проекта или файла jar в путь сборки проекта. Библиотечные проекты (и содержимое их файлов libs/*. Jar) всегда экспортируются. Это изменение влияет только на проекты только для Java и их собственные файлы jar.

Опять же, дубликаты (оба проекта и файлы jar) обнаруживаются и удаляются.

Ознакомьтесь с списком изменений.

Ответ 5

Я предполагаю, что путь Java Build для проекта среднего уровня включает проект низкого уровня. Вы проверили там проект низкого уровня (вкладка "Заказ и экспорт" )? В противном случае низкоуровневая зависимость проекта не перенаправляется на проект высокого уровня, исключая IGame из APK, который фактически вызывает сбой.

Однако это решение AFAIK не будет работать, если ваши проекты содержат специфичные для Android вещи, такие как ресурсы и т.п.

Ответ 6

Я сомневаюсь в вас и вашем проекте. С моей точки зрения, я вижу, что у вас хороший дизайн. Но почему вы работаете с Build Path / Order and Export? Честно говоря, я никогда не ходил на эту вкладку с первого дня работы с Eclipse.

Чтобы импортировать файлы jar в виде библиотек, используйте вкладку Libraries → добавить внешние банки.

И мне жаль, что я не знаю об игровом программировании, это всего лишь предложение: убедитесь, что ваш движок подходит для Android. Например, Android не поддерживает javax.imageio. Если нет, приложение может быть скомпилировано с помощью внешних банок, но может быть разбито во время выполнения.

Ответ 7

Я знаю, что это старый вопрос, но я нашел новый способ встретить эту ошибку, которая может помочь другим с недавними обновлениями.

Я получил эту ошибку от использования оператора switch/case на R.id. "константа". Последние обновления больше не считают объявления R.java постоянными в коде, даже если они объявлены окончательными. Что произойдет, так как .apk будет компилировать и устанавливать, но приносить эти ошибки Lcom.

Чтобы решить эту проблему (в Eclipse), поместите курсор в объявлении коммутатора и используйте Ctrl + 1, чтобы преобразовать переключатель в список, если then else. Обратите внимание, что если у вас есть вложенные разрывы внутри оператора case, вам нужно будет переписать этот блок кода (возможно, с дополнительным else).