Активность Android в Eclipse / ADT с зависимостями проекта (Ошибка разрешения XY) - PullRequest
11 голосов
/ 21 декабря 2011

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

В ошибку включены следующие классы / интерфейсы:

  1. (низкоуровневый) проект движка определяет этот интерфейс:

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

    com.myteam.myproject.Game
    com.myteam.myproject.MyProject (derived from com.myteam.myproject.Game)
    
  3. (верхний уровень) Android-проект осуществляет деятельность и т. Д.: * 10101 *

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

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

Но при работе с ADT происходит сбой во время выполнения, когда начинается действие. Приложение 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 "Build Path / Order and Export" проекта игры для Android, как описано в других постах и ​​форумах, но это ничего не меняет.

Я догадываюсь, что в настройках Manifest или Project нужно еще раз упомянуть зависимости пакета / класса для упаковки apk или времени выполнения. Есть идеи?

Ответы [ 7 ]

12 голосов
/ 28 марта 2012

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

  1. Проект только для Java для низкоуровневого сетевого взаимодействия
  2. Проект только для Java, чтобы абстрагировать возможности проекта низкого уровня
  3. Android-приложение

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

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

  1. В свойствах проекта приложения-> Путь сборки Java-> Проекты добавьте проекты только для Java
  2. В свойствах проекта приложения-> Путь сборки Java-> Порядок и экспорт отметьте проекты только для 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 голосов
/ 15 сентября 2012

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

Тестирование проекта Android с зависимостями jar

2 голосов
/ 12 марта 2012

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

Текущая версия плагина Eclipse ADT имеет очень негибкий предопределенный жизненный цикл сборки (особенно на этапе дексинга), очевидно, он не поддерживает группирование проектов, кроме этих трех типов проекта Android вместе (классический, библиотечный и тестовый).).Другими словами, ADT не знает, как создать свой проект Android с обычным Java-зависимым проектом под путем сборки и автоматически добавить сгенерированный зависимым проектом lib.jar в путь сборки вашего основного проекта (даже если вы добавляете их в Orderи Экспорт списка), если вы явно не добавите в него внешний файл lib.jar.Предположим, что вы добавили C: \ workspace \ game \ target \ game.jar и C: \ workspace \ engine \ target \ engine.jar в путь сборки вашего проекта android-game, команда для создания вашего файла 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», поскольку теперь он содержит не только библиотечные проекты.

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

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

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

Проверьте изменения .

2 голосов
/ 11 марта 2012

Добавьте имя ваших зависимых проектов в файл .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>
1 голос
/ 16 марта 2012

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

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

0 голосов
/ 07 июля 2013

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

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

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

0 голосов
/ 18 марта 2012

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

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

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

...