Использование действий из проектов библиотеки

У меня настроен проект Library и проект, который зависит от этого проекта библиотеки. Все компилируется нормально, и у меня, однако, проект Dependent работает нормально;

Однако у меня периодически возникают проблемы при использовании Activity из проекта Library.

Мой проект Library может быть "снят с проверки" как библиотечный проект, а действие "сборщик" может выполняться изолированно. Запуск проекта Library сам по себе работает без проблем.

Когда я использую проект Library (и действие «сборщик») из зависимого проекта, он выдает мне ошибки NullPointerExceptions (или исторически DexOp), говорящие о том, что действие «сборщик» не может найти свои ресурсы.

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

ИЗМЕНИТЬ

При ручном копировании layout.xml, используемого проектной активностью Library, в зависимый проект проект правильно открывает действие "сборщик". Это обязательно?! Конечно нет? Это еще больше заставляет меня задаться вопросом, есть ли проблема со слиянием/ссылкой на целочисленные идентификаторы из R.java в проекте Library.

ИЗМЕНИТЬ

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

Каждое из этих настраиваемых представлений имеет действие, поэтому их можно тестировать изолированно.

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

[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'listId' in package 'com.company.library.glowlist'
[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'type' in package 'com.company.library.glowlist

ИЗМЕНИТЬ

Ошибки DexOp были устранены путем удаления повторяющегося имени файла, которое присутствовало в проекте Dependent. Не уверен, что проблема была в имени файла или в содержании файла.

ИЗМЕНИТЬ

Мне пока не удалось найти решение этой проблемы (хотя ответ @yorkw, безусловно, помогает с атрибутами xml! Спасибо).

Однако мне удалось сделать эту проблему прерывистой:

Я просмотрел каждый из проектов библиотек и убедился, что все они имеют собственное пространство имен (например, com.company.library.component1, com.company.library.component2 и т. д.). После пары чисток (каждый проект заказан с правильным приоритетом) эта проблема решается сама собой, однако в конечном итоге возвращается при переключении между библиотекой/не библиотекой для тестирования компонентов.


person Graeme    schedule 01.05.2012    source источник
comment
О какой именно проблеме вы говорите? Это нечетко описано в вопросе, я не думаю, что другие могут сильно помочь, если вы не можете указать более подробную информацию. вы должны опубликовать хотя бы полное сообщение об ошибке, показанное в Eclipse, для проблемы, о которой вы упомянули в этом вопросе.   -  person yorkw    schedule 22.05.2012
comment
@yorkw Обычная ошибка NullPointerException, вызванная доступом к представлению, которое не было найдено, поскольку указанный ресурс макета не был найден (в findViewById(R.id.whatever)). Поскольку на данный момент проблема не очевидна, я не могу дать вам копипасту, но я добавлю их в следующий раз, когда она возникнет.   -  person Graeme    schedule 22.05.2012
comment
Я не могу рассказать вам больше о текущих подробностях, которые вы опубликовали, а пока внимательно прочитайте здесь. Последняя версия SDK теперь достаточно надежна и должна правильно заботиться о проекте библиотеки (компилировать исходный код, объединять ресурсы и т. д.) при очистке/сборке зависимого проекта. Вы упомянули, что у вас есть несколько библиотечных проектов, случайно ли у вас нет двухуровневой зависимости библиотечного проекта, то есть библиотечный проект 1 зависит от библиотечного проекта 2?   -  person yorkw    schedule 22.05.2012
comment
Да, я бы привел полный пример, но у меня есть 4 независимые библиотеки, которые могут работать независимо друг от друга. Зависимая библиотека, которая запускает 2 независимые библиотеки и зависимая библиотека, которая запускает зависимую библиотеку и 2 другие независимые библиотеки.   -  person Graeme    schedule 22.05.2012
comment
Ознакомьтесь с красным важным изменением в этой ссылке, это объясняет некоторые соображения о двухуровневой зависимости проекта библиотеки. Например, если у вас есть libA (com.example.liba), зависящий от libB (com.example.libb) и явно использующий import com.example.libb.R; в каком-то классе в libA, это не работает. В качестве хорошей практики не рекомендуется явно использовать import com.example.libb.R в вашем коде, так как в этом нет необходимости, и все ресурсы всегда включаются в собственный файл R основного проекта при очистке/сборке основного проекта.   -  person yorkw    schedule 24.05.2012


Ответы (5)


Причина:

Ошибка 9656: проекты библиотек не поддерживают пользовательские атрибуты XML для пользовательских классов

Решение:

Обновите SDK и ADT до последней версии (исправление было выпущено после r17) и используйте http://schemas.android.com/apk/res-auto в качестве URI пространства имен настраиваемых атрибутов, см. Редакции для ADT 17.0.0:

Добавлена ​​поддержка пользовательских представлений с пользовательскими атрибутами в библиотеках. Макеты, использующие настраиваемые атрибуты, должны использовать URI пространства имен http://schemas.android.com/apk/res-auto вместо URI, который включает имя пакета приложения. Этот URI заменяется конкретным приложением во время сборки.

Связанная тема:

Справка по пользовательским атрибутам View в библиотеке Android Проект

person yorkw    schedule 16.05.2012
comment
это странно. Я делал такие вещи в течение долгого времени, и мне никогда не приходилось устанавливать это пространство имен. они говорят, что это обязательно, но я никогда не использовал это пространство имен и никогда не имел с ним проблем. в пользовательских настройках я думаю, что у меня были проблемы. - person android developer; 17.05.2012
comment
спасибо @yorkw, это определенно решило проблему с custom attributes. - person Graeme; 17.05.2012
comment
@Graeme, если проблема решена, вы должны принять этот ответ. - person ; 22.05.2012
comment
@djaqeel Это не отвечает на вопрос - это отвечает на один из симптомов, который не был причиной проблемы. - person Graeme; 22.05.2012
comment
Я присудил награду за этот ответ, так как мне все равно пришлось бы изменить пакет настраиваемых атрибутов. Однако это не решает проблему полностью. - person Graeme; 22.05.2012

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

  1. чтобы проект Android использовал проект библиотеки Android, вы можете либо отредактировать "project.properties" и добавить туда путь к проекту библиотеки, либо, что намного проще, щелкнуть правой кнопкой мыши проект (который использует проект библиотеки), выберите категорию «android», выберите там «добавить» и выберите проект библиотеки.

  2. чтобы проект Android всегда открывал проект библиотеки Android, также выберите «путь сборки Java» -> «проекты» и выберите проект библиотеки.

  3. в «project.properties» попробуйте установить цель на одну и ту же цель для обоих проектов и на самую новую, которая у вас есть (последняя сейчас 15), даже если вы не можете протестировать приложение на этой версии Android.

  4. исходные файлы и все файлы ресурсов (в папке res) можно использовать в проектах библиотеки.

  5. папки ресурсов нельзя использовать внутри проекта библиотеки. только в проекте Android, который фактически работает, можно использовать папку с ресурсами. то же самое относится к файлу proguard.

  6. манифест библиотечных проектов почти ничего не должен иметь. см. этот пост для получения дополнительной информации: https://stackoverflow.com/a/10445630/878126. если в проекте библиотеки есть действия, к которым вы хотите иметь доступ через проект, который его использует, не забудьте включить их в манифест проекта Android (нет необходимости писать их в манифесте библиотеки Android ).

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

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

  9. если у вас есть один и тот же ресурс (любой ресурс в папке «res») как в библиотеке Android, так и в проекте Android, один в проекте Android заменит другой. это имеет преимущества и недостатки. помните, что у вас не может быть разных расширений файлов для одного и того же ресурса.

person android developer    schedule 16.05.2012
comment
7. library files can be inside the library project , but don't forget to link to them on both projects , even if it doesn't give you any compilation warnings. ‹- Это неверно, папка libs сканируется и компилируется в проект Library по состоянию на 17-е объявление. - person Graeme; 17.05.2012
comment
Можете ли вы объяснить # 8 немного больше? Что вы имеете в виду под промежуточным методом? Где будет находиться этот метод? то есть - кому принадлежит? - person Bamerza; 06.08.2014
comment
@Bamerza Я имел в виду способ переключения между новыми действиями. Я предложил сделать это путем расширения класса Application, который даст вам правильное действие для перехода. Конечно, это зависит от ваших потребностей. Возможно, вы сможете просто поместить функцию в каждое из действий, которые должны перейти к новым действиям, которые при необходимости будут переопределены. - person android developer; 06.08.2014

Проблема была вызвана тем, что файлы R из каждого из проектов Library неправильно строились и ссылались на них. Файлы ресурсов создаются и ссылаются непосредственно из вызывающего проекта.

Каждый из Libraries должен иметь уникальный пакет, как определено в AndroidManifest.xml. Это приводит к тому, что каждый из его ресурсов компилируется в этом уникальном пространстве имен в вызывающем проекте вместе с банкой Library, которая содержит файлы class.

Файлы ‹code›R‹/code›, расположенные в ситуации

Проблема становится прерывистой при переключении между библиотекой и исполняемым проектом, потому что для регенерации этих файлов необходимо выполнить clean and build, поскольку это не выполняется автоматически при снятии флажка Use as library, в то время как jar (и классы java) не требуют столько уговоров, чтобы на них правильно ссылались, поскольку библиотечные проекты ссылаются на них, действуя как Library.

Это может привести к прерывистым, а также различным ошибкам, включая отсутствующие ссылки, DexOp и NullPointerException, в зависимости от того, в какой степени файлы R.java были искажены или частично созданы и какие конфликты происходят между пакетами.

person Graeme    schedule 29.05.2012

У меня такая же проблема, как у меня есть один библиотечный проект, и у него есть какая-то активность. Когда я вызывал активность проекта библиотеки из моего основного проекта, ресурсы файлов макета не загружались должным образом для активности проекта libray и выдавали «исключение нулевого указателя» или «класс не может быть загружен» и т. д.

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

Может быть, это поможет вам.

person Nirav Shah    schedule 22.11.2012

У меня была аналогичная проблема при ссылке на проект библиотеки внутри проекта Android-приложения. Я удалил файл R.java из проекта библиотеки, чтобы он снова сгенерировался, и приложение подобрало сгенерированный файл. Вы должны увидеть сгенерированный файл R.java в вашем приложении project->gen->library_namespace_R.java.

person Omer Cansizoglu    schedule 23.09.2013