Как работает сопоставление между ресурсами android и идентификатором ресурсов?


это волшебно для Android, чтобы найти правильный ресурс только через R. id. XXX.

AFAIK, ресурсы компилируются в двоичном формате, так как же эта логика отображения работает под капотом?

может быть работает это так:

например, в layout1.xml, у нас есть:

<Button android:id="@+id/button1" >

и AAPT будет генерировать это в R.java:

public static final int button1=0x7f05000b;

когда *.apk родится, то @ + id / button1 С быть замененным с "0x7f05000b".

таким образом, когда мы называем:

findViewById(R.id.button1);

мы по существу все еще делаем поиск на основе идентификатора, хотя идентификатор-это число, подобное 0x7f05000b.

спасибо!

добавить

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

например, как найти рисованное изображение с идентификатором ресурса? Или как строковое значение с идентификатором ресурса?

5 66

5 ответов:

во время сборки инструмент aapt собирает все ресурсы, которые вы определили (хотя отдельные файлы или явные определения в файлах), и назначает им идентификаторы ресурсов.

идентификатор ресурса-это 32-разрядный номер формы: PPTTNNNN. PP-это пакет, для которого предназначен ресурс; TT-тип ресурса; NNNN-имя ресурса в этом типе. Для ресурсов приложений PP всегда равен 0x7f.

значения TT и NNNN назначаются aapt произвольно -- в основном для каждого нового типа назначается и используется следующий доступный номер (начиная с 1); аналогично для каждого нового имени в типе назначается и используется следующий доступный номер (начиная с 1).

Итак, если у нас есть эти файлы ресурсов, обрабатываемые aapt в следующем порядке:

layout/main.xml
drawable/icon.xml
layout/listitem.xml

первый тип, который мы видим, это "макет", так что задается TT == 1. Первое имя под этим типом- "main", так что дано NNNN == 1. Окончательный идентификатор ресурса-0x7f010001.

далее мы видим "drawable", так что задано TT == 2. Первое имя для этого типа - "значок", так что получает NNNN == 1. Окончательный идентификатор ресурса-0x7f020001.

в последний раз мы видим еще один "макет", который имеет TT == 1, как и раньше. Это имеет новое имя "listitem", так что получает следующее значение NNNN == 2. Окончательный идентификатор ресурса-0x7f010002.

обратите внимание, что aapt по умолчанию не пытается сохранить эти идентификаторы одинаковыми между сборками. Каждый раз, когда ресурсы меняются, они все могут получить новые идентификаторы. Каждый раз, когда они строятся, новый R.java создается с текущими идентификаторами, поэтому ваш код получает правильные значения. Из-за этого вы никогда не должны сохранять идентификаторы ресурсов в любом месте, где они могут использоваться в разных сборках вашего приложения.

после компиляции ресурсов и присвоения идентификаторов aapt генерирует R.java файл для исходного кода и двоичный файл под названием " ресурсы.РХЦ", который содержит все имена ресурсов, идентификаторы и значения (для ресурсов, которые поступают из отдельного файла, их значение-это путь к этому файлу.apk), в формате, который может легко mmapped и анализируется на устройстве во время выполнения.

вы можете получить сводку ресурсов.файл arsc в apk с командой " aapt dump resources ".

формат двоичной таблицы ресурсов описана в заголовочном файле для структур данных ресурсов здесь:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h

полная реализация для чтения таблицы ресурсов на устройстве находится здесь:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/ResourceTypes.cpp

Если вас интересует внутренняя реализация (сторона устройства), посмотрите на loadDrawable () в ресурсы.java. См. отличный ответ hackbod для получения информации о извлечение данных изтаблица ресурсов

чтобы узнать, как макеты переводятся в представление из проверки идентификатора ресурса LayoutInfater.java

насколько я понимаю, aapt автоматически генерировать уникальные идентификаторы для каждого из ресурсов и хранить их в таблице. Эта таблица сохраняется как "ресурсы.arsc "файл, расположенный в" bin/resources.ap_ " (это просто ZIP-файл, поэтому не стесняйтесь открывать его с помощью своего любимого средства просмотра ZIP). Таблица поиска также сохраняется как R.java, который, как вы знаете, позволяет ссылаться на ваши ресурсы в Java.

Если вам нужна дополнительная информация о файле ARSC, я бы предложил Гуглить его, или просматривая код http://code.google.com/p/android-apktool/.

-Дэн

последнее примечание: в течение длительного времени я не использовал относительные макеты, потому что многие элементы должны ссылаться на элементы дальше в xml-файле, и я не знал, как ссылаться на @id/foo это еще не было определено.

<!-- doesn't work -->
<TextView android:layout_above="@id/foo">above</textview>
<TextView android:id="@+id/foo">below</textview>

потом в один прекрасный день я понял, что (дух), что вы можете определение идентификатор в ссылке; он не должен быть в элементе, который несет идентификатор:

<!-- works -->
<TextView android:layout_above="@+id/foo">above</textview>
<TextView android:id="@id/foo">below</textview>

магия находится в плагине Eclipse и R.java файл он автоматически генерируется в папке "gen" приложения. Если вы заглянете в этот файл, вы увидите статические сопоставления для каждого XXX в R. xx.XXX, где xx может быть anim, массив, цвет и любой другой тип ресурса.