Скомпилированные ресурсы Android – resources.arsc

Я пытаюсь понять, что значит «скомпилировать ресурсы».

Что я сделал, чтобы понять эту проблему: я прочитал много статей о предмете, но не нашел простого ответа. Самый лучший, который я прочитал, это: Как работает сопоставление между ресурсами android ресурсов и ID ресурсов? ,

Насколько я понимаю: из моего понимания, когда мы скомпилируем наш проект либо ANT (Eclipse), либо Gradle (AS). Мы используем инструмент под названием aapt – Android Asset Packaging Tool, который: Используется для генерации уникальных идентификаторов для каждого из наших ресурсов, таких как наши макеты, наши стили и т. Д. И хранения их в справочной таблице. Затем он сохраняет эту таблицу поиска, генерируя два файла: 1. Он генерирует файл R.java с этими уникальными идентификаторами, чтобы мы могли использовать наши ресурсы из нашего java-кода во время компиляции. 2. Он генерирует файл resources.arsc, который можно найти в ресурсах * .ap_ file. Этот файл resources.arsc позже будет упакован apktool в apk.
Этот формат файла arsc – это формат, который будет легко отображаться и анализироваться устройством во время выполнения.

Пример. Итак, чтобы сделать его простым: скажем, у меня это в моей activity_main.xml:

<TextView android:id="@+id/my_textView" android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 

И я называю это из моего onCreate, используя:

 findViewById(R.id.my_textView) 

В моем файле R.java я увижу:

 public static final int my_textView=0x7f08003f; 

Использование: aap dump ресурсов в сгенерированном apk. Я вижу, что он содержит две строки с my_textView: ec resource 0x7f08003f com.example.lizi.liortest2: id / my_textView: flags = 0x00000000 ресурс 0x7f08003f com.example.lizi.liortest2: id / my_textView : T = 0x12 d = 0x00000000 (s = 0x0008 r = 0x00)

Я не понимаю: я бы подумал, что этот файл resources.arsc будет содержать не только идентификатор ресурса, но и все свойства, которые я определил для представления, например, android: layout_width = "wrap_content".

Итак, теперь во время выполнения, когда VM пытается запустить findViewById(R.id.my_textView) Как узнать, какое представление получить / его свойства для создания?

Я просто не могу понять, как это работает … разве эта таблица поиска не должна содержать данные свойств? И что это за номер 0x7f08003f? (Должен ли он представлять значение, которое впоследствии будет отображаться в физическую память, в которой будет храниться объект?)

Я понятия не имею, может ли кто-нибудь просветить меня?

Solutions Collecting From Web of "Скомпилированные ресурсы Android – resources.arsc"

Запустите эту команду, чтобы сбросить двоичный xml
aapt d xmltree apk_file_name res/layout/activity_main.xml ( aapt можно найти в android-sdk-dir / build-tools / 23.0.2 / aapt.exe )

Это покажет узлы xml (например, LinearLayout , RelativeLayout и т. Д.) С их атрибутами (например, android:layout_width, android:layout_height ) и их значениями. Значения match_parent или wrap_content можно увидеть там как отрицательные числа. Численное значение для match_parent равно 0xffffffff или -1 . Численное значение для wrap_content равно 0xfffffffe или -2 .

Собственно, вы можете использовать эту команду для любых других XML-файлов в apk, например, AndroidManifest.xml or layout files

Файл apk – это только zip-архив, содержащий все файлы классов java ( classes.dex ), все скомпилированные файлы ресурсов и файл с именем resources.arsc . Этот файл resource.arsc содержит всю метаинформацию о ресурсах и узлах xml (например, LinearLayout , RelativeLayout и т. Д.) И их атрибутах (например, android:layout_width ), включая их ids . Эти ids ссылаются на фактические ресурсы в apk-файле. Они разрешены к значению во время выполнения. Процесс разрешения @dimen/... отношении любого перенаправления ( @dimen/... в отличие от 4dp или @color/... в отличие от "#FFaabbcc" ) и возвращает значение.

Что представляет собой скомпилированный XML-файл : скомпилированный XML-файл – это тот же файл XML, в котором ссылки на ресурсы заменены на соответствующие ids . Например, ссылка @string/ok будет заменена на 0x7f000001 .

Как Android разрешает ресурсы во время выполнения : метод inflater.inflate() анализирует скомпилированный XML-файл и создает иерархию представлений путем создания экземпляров xml-узлов. Каждый из узлов xml создается экземпляром класса java (например, LinearLayout.java, RelativeLayout.java). Чтобы создать экземпляр, надуватель разбирает скомпилированный XML-файл, собирает все атрибуты узла и создает упакованную структуру типа AttributeSet . Этот AttributeSet присваивается конструктору класса. Конструктор класса несет ответственность за прохождение AttributeSet и разрешение каждого из значений атрибутов.

Например, для макета, содержащего RelativeLayout , inflater упакует layout_width и layout_height в AttributeSet и передаст его конструктору RelativeLayout (контекст контекста, AttributeSet attrs, int defStyleAttr, int defStyleRes) . В этом случае некоторые атрибуты и их значения разрешаются RelativeLayout.initFromAttributes (), а остальные – родительским ViewGroup.initFromAttributes () .

android:id представления – это еще один атрибут. Надуватель хранит идентификатор каждого вида, вызывая setId(id) на этом представлении после создания экземпляра

Теперь, чтобы ответить на ваш вопрос, R.id является массивом java, а my_textview является целым числом в этом массиве. id представления my_textview – это целое число (начинается с 0x7f). Метод findViewById() выполняет поиск по глубине в этой иерархии представлений, чтобы найти соответствующее представление.

Надеюсь это поможет. Ссылка, которую вы предоставили в своем вопросе, уже отвечает на то, как идентификаторы генерируются aapt.

Его замечательная система управления ресурсами для устройств с различными параметрами вариаций. Более того, реализация очень быстро! Благодаря этому в качестве основы он позволяет реализовать функциональность более высокого уровня (например, Runtime Resource Overlay )

LayoutInflater раздувает представление, используя строки XML. XML-строки, скомпилированные в файл ресурсов, как вы упомянули в своем вопросе.

Проверьте эти фрагменты кода AOSP:

 public View inflate(int resource, ViewGroup root, boolean attachToRoot) { final Resources res = getContext().getResources(); if (DEBUG) { Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" (" + Integer.toHexString(resource) + ")"); } final XmlResourceParser parser = res.getLayout(resource); try { return inflate(parser, root, attachToRoot); } finally { parser.close(); } } 

Resources.getLayout загружает парсер XML ресурсов

 public XmlResourceParser getLayout(int id) throws NotFoundException { return loadXmlResourceParser(id, "layout"); } XmlResourceParser loadXmlResourceParser(int id, String type) throws NotFoundException { synchronized (mAccessLock) { TypedValue value = mTmpValue; if (value == null) { mTmpValue = value = new TypedValue(); } getValue(id, value, true); if (value.type == TypedValue.TYPE_STRING) { return loadXmlResourceParser(value.string.toString(), id, value.assetCookie, type); } throw new NotFoundException( "Resource ID #0x" + Integer.toHexString(id) + " type #0x" + Integer.toHexString(value.type) + " is not valid"); } } 

getValue использует getResourceValue AssetManager и вызывает собственный метод loadResourceValue . Этот собственный метод вызывает ResTable getResource метода ResTable для получения строк XML, хранящихся в файле ресурсов.