#android #resources #android-activity #zxing
#Android #Ресурсы #android-активность #zxing
Вопрос:
Я настроил проект / android ZXing 1.7 в качестве библиотеки, на которую ссылается мой основной проект приложения для Android. В качестве быстрого теста / подтверждения концепции я использовал CaptureActivity таким же образом, как описано здесь: http://damianflannery.wordpress.com/2011/06/13/integrate-zxing-barcod …
В основном все работает хорошо, я могу запустить CaptureActivity и получить отсканированные данные в моей активности, которая ее запустила. Однако я получаю какое-то действительно странное поведение, которое, я думаю, может быть связано с конфликтом идентификаторов ресурсов между моим проектом и проектом / android ZXing. Это потребует некоторых объяснений, поэтому, пожалуйста, потерпите меня…
Я запускаю CaptureActivity с помощью этого кода:
Button scanBtn = (Button)findViewById(R.id.mainmenu_btn_scan);
scanBtn.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent("com.google.zxing.client.android.SCAN");
i.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(i, SCAN_CODE);
}
});
mainmenu_btn_scan
определяется в menu.xml:
<LinearLayout android:id="@ id/mainmenu_view" style="@style/MainMenu" xmlns:android="http://schemas.android.com/apk/res/android">
...
<Button android:id="@ id/mainmenu_btn_scan"
android:drawableTop="@drawable/btn_scan_drawable"
style="@style/MainMenuButton"
android:text="Scan"/>
...
</LinearLayout>
btn_scan_drawable.xml находится в /drawable и является drawable селектором:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/scan_btn_pressed" android:state_focused="true" android:state_pressed="true" />
...
</selector>
Проблема заключается в следующем: когда я держу телефон в горизонтальной
ориентации и запускаю CaptureActivity, я вижу, что
изображение scan_btn_pressed растягивается по экрану, а другая его копия также
растягивается на «Поместите штрих-код внутри текста прямоугольника видоискателя
…». Это происходит только тогда, когда я запускаю действие во времяудерживая
телефон в альбомной ориентации.
Я обнаружил, что если я заменю
android:drawableTop="@drawable/btn_scan_drawable"
с
android:drawableTop="@drawable/scan_btn_pressed"
Проблема исчезает, и все работает отлично, но я хочу заставить его работать с селектором (и понять, почему возникает проблема). Как объект рисования из
пользовательского интерфейса моего действия может таинственным образом отображаться в другом действии? Я новичок в разработке Android, но я весь день гуглил и работал над этой проблемой, и, похоже, я не могу понять, почему это происходит, кроме некоторых расплывчатых ссылок на конфликты идентификаторов ресурсов в документах Android.
Примечание: я использую CaptureActivity только в качестве быстрого прототипа / подтверждения концепции. Я буду реализовывать свою собственную деятельность, используя библиотеку ZXing для конечного приложения.
Ответ №1:
Хорошо, похоже, что платформа Android имеет несколько недостатков при использовании библиотечных проектов. Я заметил, что класс R моего проекта и класс R проекта библиотеки ZXing повсеместно конфликтуют, например
public static final class id {
...
public static final int mainmenu_btn_scan=0x7f070028;
...
И в классе R проекта библиотеки:
public static final class id {
...
public static final int share_app_button=0x7f070028;
...
Это объясняет, как элемент пользовательского интерфейса из моей активности был получен действием в проекте библиотеки. Android отдаст приоритет идентификаторам ресурсов в основном проекте.
Эта отличная статья дала решение: http://blog.blackmoonit.com/2010/12/android-sharing-resources-in-eclipse.html
В CaptureActivity (действие, которое я вызывал в библиотеке) я заменил
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
С помощью этого
viewfinderView = (ViewfinderView) findViewById(
getResources().getIdentifier("viewfinder_view", "id", getPackageName()) );
Это устранило проблему, хотя мне нужно будет просмотреть и заменить все прямые ссылки на идентификаторы на getIndentifier(), чтобы убедиться, что других конфликтов нет. Не идеальное решение. Похоже, что должно быть какое-то довольно простое расширение для инструмента aapt, чтобы гарантировать, что идентификаторы между R-классами не конфликтуют.
Смотрите здесь для получения дополнительной информации: http://devmaze.wordpress.com/2011/05/22/android-application-android-libraries-and-jar-libraries /
Комментарии:
1. Я думаю, что это обходное решение — вы также можете просто импортировать правильный R или использовать свой.package.R.id.viewfinder_view для дифференциации. Это скорее вопрос импорта Java. Это также подчеркивает проблему повторного использования проекта, который не предназначен для копирования, а не как проект библиотеки.
2. Я так не думаю, реальная проблема заключается в том, что в идентификаторах в классах R есть коллизии. com.somelib.R.share_app_button == com.myapp.R.mainmenu_btn_scan используется правильный файл R, но из-за коллизий и правил приоритета ресурсов Android,идентификаторы файлов библиотеки R в конечном итоге ссылаются на ресурсы в моем приложении.
3. @SeanOwen: конфликт идентификаторов ресурсов возникает из-за того, что нескольким ресурсам в разных проектах сопоставляется одно и то же целочисленное значение идентификатора. Не имеет значения, указываете ли вы в своем Java-коде имя пакета или нет — они сопоставляются с одним и тем же значением. Когда среде выполнения Android присваивается целочисленное значение идентификатора для поиска чего-либо, у нее нет информации, которая помогла бы разрешить конфликт, и поэтому она может следовать только предопределенным правилам приоритета ресурсов, которые во многих случаях приводят к неправильному результату.
Ответ №2:
использовать project->clean..
для регенерации R
класса