Jak działa mapowanie między zasobami Androida a identyfikatorem zasobów?

To magiczne dla Androida, aby zlokalizować odpowiedni zasób tylko poprzez R. id. XXX.

AFAIK, zasoby są kompilowane do formatu binarnego, więc jak ta logika mapowania działa pod maską?

Może to działa tak:

Dla np. w układzie 1.xml , mamy:

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

I AAPT wygeneruje to w R.java:

public static final int button1=0x7f05000b;

Gdy *.apk jest genrated, @ + id / button1 Z be substituded z "0x7f05000b".

Tak więc, gdy wołamy:

findViewById(R.id.button1);

Zasadniczo nadal wykonujemy wyszukiwanie na podstawie identyfikatora, chociaż identyfikator jest liczbą podobną do 0x7f05000b.

Dzięki!

Dodaj

To, co naprawdę chcę wiedzieć, to sposób, w jaki liczba całkowita identyfikatora zasobu jest parsowana do zawartości zasobu? Innymi słowy, w jaki sposób środowisko uruchomieniowe systemu Android lokalizuje zawartość zasobu z identyfikatorem zasobu jako jedyną wskazówką?

Na przykład, jak można narysować obrazek z resource id? Lub jak można znaleźć wartość łańcuchową z identyfikatorem zasobu?

Author: Jin35, 2011-06-29

5 answers

W czasie kompilacji narzędzie AAPT zbiera wszystkie zdefiniowane zasoby (choć oddzielne pliki lub wyraźne definicje w plikach) i przypisuje im identyfikatory zasobów.

Identyfikator zasobu jest 32-bitowym numerem w postaci: PPTTNNNN. PP jest pakietem, dla którego jest przeznaczony zasób; TT jest typem zasobu; NNNN jest nazwą zasobu tego typu. Dla zasobów aplikacji, PP jest zawsze 0x7f.

Wartości TT i NNNN są przypisywane przez AAPT arbitralnie - zasadniczo dla każdego nowy typ następny dostępny numer jest przypisany i używany (zaczynając od 1); podobnie dla każdej nowej nazwy w typie, następny dostępny numer jest przypisany i używany (zaczynając od 1).

Więc jeśli mamy te pliki zasobów obsługiwane przez aapt w tej kolejności:

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

Pierwszy typ, jaki widzimy, to "layout", więc podajemy TT = = 1. Pierwsza nazwa tego typu to "main", więc otrzymuje się NNNN = = 1. Ostateczny identyfikator zasobu to 0x7f010001.

Następnie widzimy "drawable" tak, że jest podane TT == 2. Pierwsza nazwa tego typu To "icon", więc otrzymuje NNNN = = 1. Ostateczny identyfikator zasobu to 0x7f020001.

Ostatni widzimy inny "układ", który ma TT = = 1 Jak wcześniej. Ma nową nazwę "listitem", więc otrzymuje następną wartość NNNN = = 2. Ostateczny identyfikator zasobu to 0x7f010002.

Zauważ, że aapt domyślnie nie próbuje zachować tych samych identyfikatorów pomiędzy kompilacjami. Za każdym razem, gdy zasoby się zmieniają, wszystkie mogą uzyskać nowe identyfikatory. Za każdym razem, gdy są budowane, nowe R.java na utworzony z bieżącymi identyfikatorami, aby Twój kod otrzymał prawidłowe wartości. Z tego powodu nigdy nie wolno utrzymywać identyfikatorów zasobów w dowolnym miejscu, w którym mogą być używane w różnych kompilacjach aplikacji.

Po skompilowaniu zasobów i przypisaniu identyfikatorów, AAPT generuje R.java Plik z kodem źródłowym oraz plik binarny o nazwie "resources.arsc", który zawiera wszystkie nazwy zasobów, identyfikatory i wartości (dla zasobów pochodzących z oddzielnego pliku ich wartością jest ścieżka do tego pliku w .apk), w formacie, który w czasie wykonywania może być łatwo przetwarzany i przetwarzany na urządzeniu.

Możesz uzyskać podsumowanie zasobów.plik arsc w apk z poleceniem " AAPT dump resources ".

Format tabeli zasobów binarnych jest udokumentowany w pliku nagłówkowym dla struktur danych zasobów tutaj:

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

Pełna implementacja do odczytu tabeli zasobów na urządzeniu znajduje się tutaj:

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

 167
Author: hackbod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-14 18:47:57

Jeśli jesteś zainteresowany wewnętrzną implementacją (po stronie urządzenia), zajrzyj do loadDrawable () w zasobach .java . Zapoznaj się z doskonałą odpowiedzią hackbod na informacje o wydobywaniu danych z tabela zasobów

Aby dowiedzieć się, jak układy są tłumaczone na widok z zasobu ID sprawdź LayoutInfater.java

 7
Author: Reno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 23:13:26

Z tego, co rozumiem, aapt automatycznie wygeneruje unikalne identyfikatory dla każdego z Twoich zasobów i zapisze je w tabeli wyszukiwania. Ta tabela jest utrzymywana jako " zasoby.arsc "plik znajdujący się w" bin/resources.ap_ " (jest to tylko plik ZIP, więc możesz go otworzyć za pomocą ulubionej przeglądarki ZIP). Tabela jest również utrzymywana jako R.java, co jak wiadomo pozwala na odwoływanie się do zasobów w Javie.

Jeśli chcesz więcej informacji na temat pliku ARSC, proponuję Googlować it, czyli przegląd kodu http://code.google.com/p/android-apktool/.

-Dan

 5
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-05 12:02:12

Ostatnia uwaga: przez dłuższy czas nie używałem układów względnych, ponieważ wiele elementów musi odwoływać się do elementów znajdujących się dalej w pliku xml, i nie wiedziałem, jak odwoływać się do @id/foo, które nie zostały jeszcze zdefiniowane.

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

Pewnego dnia zdałem sobie sprawę (duh), że można zdefiniować identyfikator W referencji; nie musi być w elemencie, który nosi identyfikator:

<!-- works -->
<TextView android:layout_above="@+id/foo">above</textview>
<TextView android:id="@id/foo">below</textview>
 1
Author: Edward Falk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-14 16:29:00

Magia jest w Plug-in Eclipse i R.java plik to autogenerates w aplikacji w folderze "gen". Jeśli zajrzysz do tego pliku, zobaczysz statyczne mapowania dla każdego XXX w R. xx.XXX, gdzie xx może być anim, tablicą, kolorem i każdym innym typem zasobu.

 0
Author: ErikR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-29 07:46:01