Использование URL-адреса file:///android_res/drawable/ работает в eclipse, но не в производстве

У меня есть проблема, которая сводит меня с ума. У меня есть статический html-файл (assets/help/index.html), который должен содержать изображения. Поскольку мне нужны разные изображения для разных плотностей, а изображения уже включены в drawable-{ldpi,mdpi,hdpi}, я подумал, что буду использовать следующий HTML-код:

<img src="file:///android_res/drawable/image.png">

Это отлично работает под затмением! К сожалению, в производственной версии (сборка с плагином maven для Android) веб-просмотр, отображающий html-страницу, показывает значки сломанных изображений.

Я попытался открыть страницу, используя loadUrl и loadDataWithBaseUrl (сначала прочитав файл сам), последний с базовым URL-адресом file:///android_res/drawable. Обе попытки успешны в eclipse, но терпят неудачу в версии maven.

Итак, я распаковал как сгенерированный Eclipse apk, так и сгенерированный maven, и сделал diff -r между ними, потому что явно должна быть разница.

Я сбит с толку, обнаружив только несколько тривиальных различий (в основном различия в подписи, поскольку apk eclipse подписан сертификатом отладки, а maven - моим официальным сертификатом). Кроме того, содержимое apks идентично!

Кто-нибудь знает, что происходит или как продолжить раскрытие дополнительной информации?


person Pieter    schedule 19.05.2011    source источник


Ответы (3)


У меня была аналогичная проблема с использованием proguard, и я нашел объяснение (и решение!) здесь.

В моем случае proguard запутал класс R, и android_res/[...] больше не мог быть найден.

Я решил добавить правило в proguard.cfg:

-keepclassmembers class **.R$* {
    public static <fields>;
}

-keep class **.R$*

Я не знаю о maven, но надеюсь, что это поможет.

person j.c    schedule 22.02.2014
comment
Это правильный ответ, @pieter должен его принять. IDE, по-видимому, исключает сгенерированный код из обработки proguard, в то время как сборка maven использует прямой вызов proguard, что приводит к запутыванию этих классов, если не указаны соответствующие правила. Правила, данные j.c. достаточно точны, мне помогли. - person zysoft; 18.11.2014

Есть причины использовать file:///android_res вместо file:///android_asset. Один из них заключается в том, что в проектах библиотек Android не может быть ресурсов.

Если вы хотите получить доступ к ресурсам, которые определены в проекте библиотеки, из WebView и переименуйте имя пакета, используя соответствующую опцию android-maven-plugin (который, в свою очередь, зависит от некоторого Android SDK feature), то вы столкнулись с довольно странной ошибкой.

Android делает это в android.webkit.BrowserFrame::inputStreamForAndroidResource (по крайней мере, в 4.1.2):

final Class<?> d = mContext.getApplicationContext().getClassLoader().loadClass(
mContext.getPackageName() + ".R$" + subClassName);

Это динамический поиск класса R, и он использует имя пакета приложения в качестве имени пакета Java. Однако это не работает, потому что класс R в переименованном имени пакета не будет существовать.

Возможный обходной путь: во время сборки выпуска динамически создайте копию реального класса R и поместите ее в пакет Java, который соответствует переименованному имени пакета приложения. Не забудьте также обновить оператор package в скопированном исходном коде.

person rob    schedule 16.11.2012

Я бы рассмотрел AsssetManager как способ доступа файлы в комплекте с приложением. Учебник (с примером кода) можно найти здесь. В качестве альтернативы вы можете поместить файл в res/raw и прочитать его с помощью openRawResource()

person ProfSmiles    schedule 27.12.2011