2015-10-28 2 views
1

В моем приложении для Android я создал библиотеку, которая разделяет некоторые строковые ресурсы с основным проектом.Отсутствие опциональной концепции пространства имен в слиянии ресурсов Android

Main project --------------> main resources (e.g. string) 
library project -----------> library resources (e.g. string) 

Давайте предположит, что:

<string name="app_name">The new app name</string> (in main) 
<string name="app_name">The standard app name</string> (in library) 

Google утверждает, что есть слияние во время компиляции и рекомендует использовать жёстко прописанные префиксы на уровне ресурсов для предотвращения слияния:

В тех случаях, когда Идентификатор ресурса определяется как в приложении, так и в библиотеке, инструменты обеспечивают, чтобы ресурс, объявленный в приложении, получил приоритет и что ресурс в проекте библиотеки не скомпилирован в приложение .ap к. Это дает вашему приложению гибкость в использовании или переопределении любых типов поведения ресурсов или значений, определенных в любой библиотеке.

Я думаю, что у меня есть сочетание необходимых поведения:

  • для некоторых ресурсов, которые я хочу библиотека использует ресурс перекрываться основным ресурсом
  • для некоторых ресурсов, которые я хочу библиотека продолжает использовать свои собственные библиотечные ресурсы без слияния

Я думаю, что жесткая кодировка префикса noec но я бы ожидал, что google предоставит вид attr, для каждого файла ресурсов или каждого ресурса, к необязательно внутреннему префиксу (с чем-то именем пакета), чтобы разработчик мог получить доступ к ресурсу, недоступному для переопределения. Что-то как:

<string name="app_name" prefix="yes"></string> 

(«префикс» атр добавленного мной поручив компилятор, чтобы сохранить ресурс, как, например, package_name.app_name для предотвращения слияния с app_name) и в библиотеке коды доступ будет строка, как

getResources().getPrefixedString(R.id.app_name) 

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

getResources().getIdentifier("res_name", "res_type", "com.library.package"); 

но есть 3 недостатков с этим подходом, если я хочу, чтобы вручную смоделировать такое поведение:

  1. более низкую производительность
  2. Я до сих пор, чтобы добавить свой жёстко пространство имен в качестве префикса для всех требуемых строк и
  3. ресурсы не могут быть вызваны из самого XML (если вы не жёстко префикс, а).

Есть ли в настоящее время какой-либо механизм для указания компилятора, если я хочу объединить ресурс или нет?

+0

«Я думаю, что у меня есть сочетание требуемого поведения» - почему существует ваш второй маркированный сценарий? Просто не определяйте ресурс в приложении, поэтому он извлекает его из библиотеки. – CommonsWare

+0

моя строка определена в 2 библиотеках плюс необязательное основное приложение, и я ожидаю, что каждая библиотека будет потреблять свой собственный ресурс, а не переопределять. Вот почему я ожидаю, что смогу опционально определить какое-то пространство имен, чтобы предотвратить слияние ресурсов библиотеки. – pellyadolfo

+0

Пример: ваше приложение использует 2 библиотеки. Оба имеют одинаковые имена ресурсов. Какой ресурс будет использоваться этим именем? – m0rphine

ответ

4

Есть ли в настоящее время какой-либо механизм для указания компилятора, если я хочу объединить ресурс или нет?

Не так, как вы ожидаете, за ваши комментарии.

Вот почему я ожидал бы возможность дополнительно определять вид пространства имен для предотвращения слияния библиотечных ресурсов

Это не поддерживается автоматической сборки в это время. Префиксы для сохранения уникальности ресурсов зависят от разработчика.

Вы, безусловно, можете написать свои собственные инструменты, чтобы помочь себе в этой области. Например, вы можете написать задачу Gradle, которая исследует релевантные ресурсы и, если им не хватает префикса, и не имеют какого-либо атрибута XML, чтобы сказать «игнорировать этот», не удается построить.

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

Это не работает так, как вы ожидаете.

Похоже, что библиотеки имеют ресурсы, не зависящие от приложения. Это неверно. Библиотеки вносят ресурсов в приложение, но все ресурсы являются частью одного большого пула. Следовательно, вы не можете использовать getIdentifier() и предоставить некоторое имя библиотеки и вернуть значение. Вы предоставляете идентификатор приложения и получаете один ресурс в этом приложении, соответствующий вашим критериям (при условии, что такой ресурс существует). Является ли этот ресурс из библиотеки или из модуля приложения, не имеет значения.

+0

Да, я понял ваш последний комментарий только сейчас. Я не могу не знать в библиотеке, которая является его packagename как библиотека. Таким образом, единственное решение, которое я могу вычислить, чтобы иметь сосуществующие полиморфные библиотеки, - это жесткое кодирование рукописного префикса и использование его в качестве префикса для всех ресурсов для этой библиотеки. На самом деле беспорядок. – pellyadolfo

+0

и он не будет работать для XML, поэтому мне нужно setText() в коде – pellyadolfo

Смежные вопросы