Ten dokument opisuje układ i zawartość plików .dex
, które służą do przechowywania zestawu definicji klas i powiązanych z nimi danych pomocniczych.
Przewodnik po typach
Nazwa | Opis |
---|---|
bajt | 8-bitowa liczba całkowita ze znakiem |
ubyte | 8-bitowa liczba bez znaku typu int |
krótki | 16-bitowa liczba całkowita ze znakiem w systemie little-endian |
ushort | 16-bitowa bez znaku int, małe endian |
int | 32-bitowa liczba całkowita ze znakiem, małe endian |
uint | 32-bitowa bez znaku int, małe endian |
długi | 64-bitowa liczba całkowita ze znakiem, małe endian |
ulong | 64-bitowa bezznakowa int, little-endian |
sleb128 | podpisany LEB128 o zmiennej długości (patrz poniżej) |
uleb128 | bez znaku LEB128 o zmiennej długości (patrz poniżej) |
uleb128p1 | bez znaku LEB128 plus 1 o zmiennej długości (patrz poniżej) |
LEB128
LEB128 („Little-Endian Base 128”) to kodowanie o zmiennej długości dla dowolnych wartości całkowitych ze znakiem lub bez znaku. Format został zapożyczony ze specyfikacji DWARF3. W pliku .dex
kod LEB128 jest używany tylko do kodowania wartości 32-bitowych.
Każda wartość zakodowana w formacie LEB128 składa się z 1–5 bajtów, które razem stanowią pojedynczą 32-bitową wartość. Każdy bajt ma ustawiony najbardziej znaczący bit, z wyjątkiem ostatniego bajtu w sekwencji, którego najbardziej znaczący bit jest pusty. Pozostałe 7 bitów każdego bajta to ładunek użyteczny, przy czym 7 najmniej istotnych bitów wartości w pierwszym bajcie, 7 następnych w drugim itd. W przypadku podpisanego LEB128 (sleb128
) najbardziej znaczący bit danych w ostatnim bajcie sekwencji jest rozszerzany o znak, aby uzyskać ostateczną wartość. W przypadku liczb bez znaku (uleb128
) wszystkie bity, które nie są wyraźnie reprezentowane, są interpretowane jako 0
.
Diagram bitowy dwubajtowej wartości LEB128 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Pierwszy bajt | Drugi bajt | ||||||||||||||
1 |
bitów6 | bitów5 | bitów4 | bit3 | bit2 | bit1 | bitów0 | 0 |
bit13 | bitów12 | bitów11 | bit10 | bitów9 | bitów8 | bitów7 |
Wariant uleb128p1
służy do reprezentowania wartości ze znakiem, gdzie reprezentacja ma wartość plus 1 zakodowana jako uleb128
. Dzięki temu kodowanie wartości -1
(czyli nieoznaczonej wartości 0xffffffff
) – ale nie innych wartości ujemnych – zajmuje 1 bajt. Jest to przydatne w tych przypadkach, gdy reprezentowana liczba musi być nieujemna lub równa -1
(lub 0xffffffff
), a nie są dozwolone inne wartości ujemne (lub gdy duże wartości bez znaku są mało prawdopodobne).
Oto kilka przykładów formatów:
Sekwencja zakodowana | sleb128 |
uleb128 |
uleb128p1 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7f | -1 | 127 | 126 |
80 7f | -128 | 16256 | 16255 |
Układ pliku
Nazwa | Format | Opis |
---|---|---|
nagłówek | header_item | nagłówek |
string_ids | string_id_item[] | lista identyfikatorów ciągu znaków. Są to identyfikatory wszystkich ciągów znaków używanych przez ten plik, albo do wewnętrznego nazewnictwa (np. opisy typów), albo jako obiekty statyczne odwołujące się do kodu. Lista musi być posortowana według zawartości ciągu znaków za pomocą wartości punktów kodu UTF-16 (nie w sposób zależny od lokalizacji) i nie może zawierać zduplikowanych wpisów. |
type_ids | type_id_item[] | typów identyfikatorów. Są to identyfikatory wszystkich typów (klas, tablic lub typów prymitywnych), do których odwołuje się ten plik, niezależnie od tego, czy są zdefiniowane w pliku. Lista musi być posortowana według indeksu string_id i nie może zawierać zduplikowanych wpisów.
|
proto_ids | proto_id_item[] | listę identyfikatorów prototypu metody. To są identyfikatory wszystkich prototypów, do których odnosi się ten plik. Lista ta musi być posortowana według typu zwracanego (według indeksu type_id ), a następnie według listy argumentów (kolejność leksykograficzna, poszczególne argumenty posortowane według indeksu type_id ). Lista nie może zawierać zduplikowanych pozycji.
|
field_ids | field_id_item[] | lista identyfikatorów pól. Są to identyfikatory wszystkich pól, do których odwołuje się ten plik, niezależnie od tego, czy są one w nim zdefiniowane. Ta lista musi być posortowana, przy czym definiujący typ (według indeksu type_id ) jest głównym elementem, nazwa pola (według indeksu string_id ) jest elementem pośrednim, a typ (według indeksu type_id ) jest elementem podrzędnym. Lista nie może zawierać zduplikowanych pozycji.
|
method_ids | method_id_item[] | lista identyfikatorów metody. Są to identyfikatory wszystkich metod, do których odwołuje się ten plik, niezależnie od tego, czy są zdefiniowane w pliku. Ta lista musi być posortowana, przy czym typ definiujący (według indeksu type_id ) ma najwyższy priorytet, nazwa metody (według indeksu string_id ) ma priorytet pośredni, a prototyp metody (według indeksu proto_id ) ma najniższy priorytet. Lista nie może zawierać zduplikowanych pozycji.
|
class_defs | class_def_item[] | lista definicji klas. Klasy muszą być uporządkowane w taki sposób, aby superklasa danej klasy i zaimplementowane interfejsy były na liście wcześniej niż klasa referencyjna. Ponadto definicja klasy o tej samej nazwie nie może występować więcej niż raz na liście. |
call_site_ids | call_site_id_item[] | lista identyfikatorów witryn wywołania. Są to identyfikatory wszystkich miejsc wywołania, do których odwołuje się ten plik, niezależnie od tego, czy są w nim zdefiniowane. Ta lista musi być posortowana w kolejności rosnącej według kolumny call_site_off .
|
method_handles | method_handle_item[] | metody. Lista wszystkich uchwytów metody używanych przez ten plik, niezależnie od tego, czy są zdefiniowane w pliku. Ta lista nie jest posortowana i może zawierać zduplikowane pozycje, które logicznie odpowiadają różnym instancjom uchwytu metody. |
dane | ubyte[] | obszar danych zawierający wszystkie dane pomocnicze dotyczące wymienionych powyżej tabel. Różne elementy mają różne wymagania dotyczące wyrównania. W razie potrzeby przed każdym elementem wstawiane są bajty wypełnienia, aby zapewnić prawidłowe wyrównanie. |
link_data | ubyte[] | dane używane w plikach połączonych statycznie. Format danych w tej sekcji nie jest określony w tym dokumencie. Ta sekcja jest pusta w niepołączonych plikach, a implementacje w czasie wykonywania mogą jej używać według uznania. |
Format kontenera
Wersja 41 wprowadza nowy format kontenera danych DEX, który ma na celu oszczędzanie miejsca. Ten format kontenera umożliwia połączenie kilku logicznych plików DEX w jeden fizyczny plik. Nowy format to głównie proste złączenie plików w poprzednim formacie, z kilkoma różnicami:
file_size
to rozmiar pliku logicznego, a nie fizycznego. Można go użyć do iteracji po wszystkich plikach logicznych w kontenerze.- Logiczne pliki dex mogą odwoływać się do dowolnych późniejszych danych w kontenerze (ale nie wcześniejszych). Dzięki temu pliki dex mogą udostępniać sobie dane, np. ciągi znaków.
- Wszystkie przesunięcia są względne względem fizycznego pliku. Brak przesunięcia względem nagłówka. Dzięki temu sekcje z przesunięciem mogą być udostępniane między plikami logicznymi.
- Nagłówek dodaje 2 nowe pola opisujące granice kontenera. Jest to dodatkowa kontrola spójności, która ułatwia przenoszenie kodu do nowego formatu.
- Funkcje
data_size
idata_off
nie są już używane. Dane mogą być rozproszone w wielu plikach logicznych i nie muszą być ciągłe.
Definicje pól bitowych, ciągów tekstowych i stałych
DEX_FILE_MAGIC
Umieszczony w header_item
Stałe tablice/ciągi znaków DEX_FILE_MAGIC
to lista bajtów, która musi znajdować się na początku pliku .dex
, aby był on rozpoznawany jako taki. Wartość celowo zawiera znak końca wiersza ("\n"
lub 0x0a
) oraz bajt null ("\0"
lub 0x00
), aby ułatwić wykrywanie pewnych form uszkodzenia. Wartość ta koduje również numer wersji formatu jako 3 cyfry dziesiętne, które powinny rosnąć monotonicznie wraz z rozwojem formatu.
ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 } = "dex\n039\0"
Uwaga: w wersji 10.0 systemu Android dodano obsługę wersji 040
formatu, która rozszerzyła zestaw dozwolonych znaków w SimpleNames.
Uwaga: obsługa wersji 039
tego formatu została dodana w wersji Androida 9.0, która wprowadziła 2 nowe bajtkody: const-method-handle
i const-method-type
. (są one opisane w tabeli Podsumowanie zestawu kodu bajtowego). W Androidzie 10 w wersji 039
format pliku DEX został rozszerzony o ukryte informacje API, które dotyczą tylko plików DEX na ścieżce klasy uruchamiania.
Uwaga: w wersji 8.0 Androida dodano obsługę wersji 038
tego formatu. W wersji 038
dodano nowe bajtkody (invoke-polymorphic
i invoke-custom
) oraz dane dotyczące uchwytów metod.
Uwaga: obsługa wersji 037
tego formatu została dodana w wersji 7.0 Androida. Przed wersją 037
większość wersji Androida używała wersji 035
tego formatu. Jedyną różnicą między wersjami 035
i 037
jest dodanie domyślnych metod i dostosowanie invoke
.
Uwaga: co najmniej kilka wcześniejszych wersji tego formatu było używanych w publicznych wersjach oprogramowania dostępnych dla szerokiego grona użytkowników. Na przykład wersja 009
była używana w przypadku wersji M3 platformy Android (listopad–grudzień 2007 r.), a wersja 013
– w przypadku wersji M5 tej platformy (luty–marzec 2008 r.). W kilku aspektach te wcześniejsze wersje formatu różnią się znacznie od wersji opisanej w tym dokumencie.
ENDIAN_CONSTANT i REVERSE_ENDIAN_CONSTANT
Umieszczony w header_item
Stała ENDIAN_CONSTANT
służy do wskazywania kodowania bajtów pliku, w którym się znajduje. Chociaż standardowy format .dex
jest little-endian, implementacje mogą przeprowadzić zamianę bajtów. Jeśli implementacja napotka nagłówek, którego endian_tag
to REVERSE_ENDIAN_CONSTANT
zamiast ENDIAN_CONSTANT
, będzie wiedzieć, że bajty w pliku zostały zamienione w nieoczekiwanej formie.
uint ENDIAN_CONSTANT = 0x12345678; uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
NO_INDEX
Umieszczone w elementach class_def_item i debug_info_item
Wartość stała NO_INDEX
wskazuje, że wartość indeksu jest nieobecna.
Uwaga: ta wartość nie jest zdefiniowana jako 0
, ponieważ jest to zwykle prawidłowy indeks.
Wybrana wartość NO_INDEX
może być reprezentowana jako pojedynczy bajt w kodowaniu uleb128p1
.
uint NO_INDEX = 0xffffffff; // == -1 if treated as a signed int
definicje access_flags
Umieszczone w elementach class_def_item, encoded_field, encoded_method i InnerClass.
Pola bitowe tych flag służą do wskazywania właściwości ułatwień dostępu i ogólnych właściwości klas i elementów klasy.
Nazwa | Wartość | Zajęcia (i adnotacje InnerClass ) |
Pola | Metody |
---|---|---|---|---|
ACC_PUBLIC | 0x1 | public : widoczne wszędzie |
public : widoczne wszędzie |
public : widoczne wszędzie |
ACC_PRIVATE | 0x2 | private : widoczne tylko dla klasy definiującej
|
private : widoczne tylko dla klasy definiującej |
private : widoczne tylko dla klasy definiującej |
ACC_PROTECTED | 0x4 | protected : widoczne dla pakietu i podklas
|
protected : widoczne dla pakietu i podklas, |
protected : widoczne dla pakietu i podklas, |
ACC_STATIC | 0x8 | static : nie jest konstruowany z poziomu zewnętrznym
this odniesienie |
static : globalny do zdefiniowania klasy |
static : nie przyjmuje argumentu this |
ACC_FINAL | 0x10 | final : nie można utworzyć podklasy |
final : nie można zmienić po utworzeniu |
final : nie można zastąpić |
ACC_SYNCHRONIZED | 0x20 | synchronized : powiązany blokada jest automatycznie nabywany w okresie wywołania tej metody. Uwaga: to ustawienie jest prawidłowe tylko wtedy, gdy |
||
ACC_VOLATILE | 0x40 | volatile : specjalne reguły dostępu ułatwiające bezpieczne prowadzenie wątku |
||
ACC_BRIDGE | 0x40 | metoda mostu, dodana automatycznie przez kompilator jako bezpieczna pod względem typów; | ||
ACC_TRANSIENT | 0x80 | transient : nie należy zapisywać za pomocą domyślnej serializacji |
||
ACC_VARARGS | 0x80 | ostatni argument powinien być traktowany przez kompilator jako argument „reszta” | ||
ACC_NATIVE | 0 x 100 | native : zaimplementowany w kodzie natywnym |
||
ACC_INTERFACE | 0 x 200 | interface : abstrakcyjna klasa z wieloma implementacjami |
||
ACC_ABSTRACT | 0x400 | abstract : nie można utworzyć bezpośrednio |
abstract : nie jest obsługiwane przez tę klasę |
|
ACC_STRICT | 0x800 | strictfp : ścisłe reguły dotyczące obliczeń zmiennoprzecinkowych |
||
ACC_SYNTHETIC | 0x1000 | nie są bezpośrednio zdefiniowane w kodzie źródłowym; | nie są bezpośrednio zdefiniowane w kodzie źródłowym; | nie są bezpośrednio zdefiniowane w kodzie źródłowym; |
ACC_ANNOTATION | 0x2000 | zadeklarowana jako klasa adnotacji, | ||
ACC_ENUM | 0x4000 | zadeklarowany jako typ wyliczeniowy. | zadeklarowana jako wartość wyliczeniowa | |
(nieużywany) | 0x8000 | |||
ACC_CONSTRUCTOR | 0x10000 | metoda konstruktora (inicjator klasy lub wystąpienia); | ||
ACC_DECLARED_ SYNCHRONIZED |
0x20000 | Zadeklarowano synchronized . Uwaga: nie ma to wpływu na wykonanie (poza odzwierciedleniem tej flagi). |
InnerClass
. Nie można ich używać w przypadku adnotacji class_def_item
.
Zmodyfikowane kodowanie UTF-8
W ramach ułatwienia obsługi starszych wersji format .dex
koduje dane ciągu znaków w formie de facto standardowej zmodyfikowanej wersji UTF-8, zwanej dalej MUTF-8. Ten format jest identyczny ze standardowym UTF-8, z tym wyjątkiem, że:
- Używane są tylko kodowania jedno-, dwu- i trzybajtowe.
- Punkty kodu z zakresu
U+10000
…U+10ffff
są kodowane jako para zastępcza, z której każda jest reprezentowana jako 3-bajtowa wartość zakodowana. - Punkt kodu
U+0000
jest kodowany w postaci 2-bajtowej. - Prosty bajt null (wartość
0
) wskazuje koniec ciągu, zgodnie ze standardową interpretacją w języku C.
Pierwsze 2 punkty można podsumować w ten sposób: MUTF-8 to kodowanie UTF-16, a nie bezpośredni format kodowania znaków Unicode.
Ostatnie 2 elementy umożliwiają jednoczesne uwzględnienie punktu kodu U+0000
w ciągu znaków i dalsze manipulowanie nim jako ciągiem znaków zakończonym zerem w stylu C.
Jednak specjalne kodowanie U+0000
oznacza, że w przeciwieństwie do normalnego UTF-8 wynik wywołania standardowej funkcji C strcmp()
na parze ciągów tekstowych MUTF-8 nie zawsze wskazuje prawidłowo podpisany wynik porównania ciągów nierównych.
Jeśli istotne jest sortowanie (a nie tylko sprawdzanie równości), najprostszym sposobem porównywania ciągów znaków MUTF-8 jest ich dekodowanie znak po znaku i porównywanie uzyskanych wartości. Możliwe są też bardziej zaawansowane implementacje.
Więcej informacji o kodowaniu znaków znajdziesz w standardzie Unicode. Kodowanie MUTF-8 jest w większym stopniu podobne do (relatywnie mniej znanego) kodowania CESU-8 niż do UTF-8.
encoded_value kodowanie
Umieszczone w elementach annotation_element i encoded_array_item
encoded_value
to zakodowany element (prawie) dowolnych danych uporządkowanych hierarchicznie. Kodowanie ma być zwięzłe i łatwe do zanalizowania.
Nazwa | Format | Opis |
---|---|---|
(value_arg << 5) | value_type | ubyte | bajt określający typ bezpośrednio następnego value z opcjonalnym argumentem wyjaśniającym w 3 najstarszych bitach.
Poniżej znajdziesz różne definicje value .
W większości przypadków value_arg koduje długość bezpośrednio następnego value w bajtach, jako (size - 1) , np. 0 oznacza, że wartość wymaga 1 bajta, a 7 – 8 bajtów. Istnieją jednak wyjątki, o których mowa poniżej.
|
wartość | ubyte[] | bajty reprezentujące wartość, o zmiennej długości i interpretowane w zależności od różnych bajtów value_type , ale zawsze w systemie little-endian. Poniżej znajdziesz definicje poszczególnych wartości.
|
Formaty wartości
Wpisz nazwę | value_type |
value_arg Format |
value Format |
Opis |
---|---|---|---|---|
VALUE_BYTE | 0x00 | (brak; musi być 0 ) |
ubyte[1] | o wartości całkowitej ze znakiem w 1 bajcie. |
VALUE_SHORT | 0x02 | rozmiar - 1 (0…1) | ubyte[size] | dwubajtowa liczba całkowita ze znakiem, rozszerzona o znak; |
VALUE_CHAR | 0x03 | rozmiar - 1 (0…1) | ubyte[size] | bez znaku, 2-bajtowa wartość liczby całkowitej, rozszerzona do pełnego rozmiaru za pomocą zera |
VALUE_INT | 0x04 | size - 1 (0…3) | ubyte[size] | 4-bajtowa liczba całkowita ze znakiem, z rozszerzonym znakiem. |
VALUE_LONG | 0x06 | size - 1 (0…7) | ubyte[size] | ośmiobajtowa liczba całkowita ze znakiem, z rozszerzeniem znaku; |
VALUE_FLOAT | 0x10 | size - 1 (0…3) | ubyte[size] | czterobajtowy wzór bitów rozszerzony zera w prawo i interpretowany jako 32-bitowa wartość zmiennoprzecinkowa IEEE754 |
VALUE_DOUBLE | 0x11 | size - 1 (0…7) | ubyte[size] | ośmiobajtowy wzór bitów rozszerzony o zera w prawo i interpretowany jako 64-bitowa wartość zmiennoprzecinkowa IEEE754. |
VALUE_METHOD_TYPE | 0 x 15 | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzona o 0) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji proto_ids i reprezentująca wartość typu metody
|
VALUE_METHOD_HANDLE | 0x16 | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzony o 0) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji method_handles i reprezentująca wartość uchwytu metody
|
VALUE_STRING | 0x17 | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzona o 0) wartość liczby całkowitej o cztery bajty, interpretowana jako indeks w sekcji string_ids i reprezentująca wartość ciągu znaków
|
VALUE_TYPE | 0 x 18 | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzony o zerowanie) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji type_ids i reprezentująca wartość typu/klasy odbicienia
|
VALUE_FIELD | 0x19 | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzony o zerowanie) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji field_ids i przedstawiająca wartość pola odzwierciedlonego
|
VALUE_METHOD | 0x1a | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzony o zerowanie) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji method_ids i przedstawiająca wartość metody odzwierciedlającej
|
VALUE_ENUM | 0x1b | size - 1 (0…3) | ubyte[size] | bez znaku (rozszerzona o zerowanie) wartość całkowita o cztery bajty, interpretowana jako indeks w sekcji field_ids i przedstawiająca wartość stałej typu wyliczonego
|
VALUE_ARRAY | 0x1c | (brak; musi być 0 ) |
encoded_array | tablica wartości w formacie określonym przez „format encoded_array ” poniżej. Rozmiar value jest domyślnie określony w kodzie.
|
VALUE_ANNOTATION | 0x1d | (brak; musi być 0 ) |
encoded_annotation | adnotację podrzędną w formacie określonym przez „format encoded_annotation ” poniżej. Rozmiar value jest domyślnie uwzględniony w kodowaniu.
|
VALUE_NULL | 0x1e | (brak; musi być 0 ) |
(brak) | null wartość referencyjna |
VALUE_BOOLEAN | 0x1f | wartość logiczna (0…1) | (brak) | wartość jednobitowa: 0 dla false i 1 dla true . Bit jest reprezentowany w value_arg .
|
Format encoded_array
Nazwa | Format | Opis |
---|---|---|
rozmiar | uleb128 | liczba elementów w tablicy |
wartości | encoded_value[size] | sekwencja size encoded_value bajtów w formacie określonym w tej sekcji, połączonych sekwencyjnie.
|
Format encoded_annotation
Nazwa | Format | Opis |
---|---|---|
type_idx | uleb128 | typ adnotacji. Musi to być typ klasy (a nie tablicy ani typu prymitywnego). |
rozmiar | uleb128 | Liczba mapowań nazwa-wartość w tej adnotacji |
elementów | annotation_element[size] | elementy adnotacji, reprezentowane bezpośrednio w wierszu (nie jako przesunięcia). Elementy muszą być posortowane w kolejności rosnącej według indeksu string_id .
|
Format annotation_element
Nazwa | Format | Opis |
---|---|---|
name_idx | uleb128 | nazwa elementu, która jest indeksem w sekcji
string_ids . Ciąg musi być zgodny ze składnią NazwaCzłonka zdefiniowaną powyżej.
|
wartość | encoded_value | wartość elementu |
Składnia ciągu znaków
W pliku .dex
występuje kilka rodzajów elementów, które ostatecznie odwołują się do ciągu znaków. Definicje w stylu BNF wskazują dopuszczalną składnię tych ciągów znaków.
SimpleName
SimpleName jest podstawą składni nazw innych rzeczy. Format .dex
daje dużą swobodę (znacznie większą niż w przypadku większości języków źródłowych). Krótko mówiąc, prosta nazwa składa się z dowolnego znaku alfabetycznego lub cyfry z dolnego zakresu ASCII, kilku określonych symboli z dolnego zakresu ASCII oraz większości punktów kodu spoza ASCII, które nie są znakami kontrolnymi, spacją ani znakami specjalnymi. Od wersji 040
format ten umożliwia również stosowanie znaków spacji (kategoria znaków Unicode Zs
). Pamiętaj, że punkty kodu zastępczego (w zakresie U+d800
…U+dfff
) nie są uznawane za prawidłowe znaki nazwy, ale dodatkowe znaki Unicode są prawidłowe (co jest reprezentowane przez ostatnią alternatywę reguły SimpleNameChar), i powinny być reprezentowane w pliku jako pary punktów kodu zastępczego w koderze MUTF-8.
SimpleName → | ||
SimpleNameChar (SimpleNameChar)* | ||
SimpleNameChar → | ||
'A' … 'Z' |
||
| | 'a' … 'z' |
|
| | '0' … '9' |
|
| | ' ' |
od wersji DEX 040 |
| | '$' |
|
| | '-' |
|
| | '_' |
|
| | U+00a0 |
od wersji DEX 040 |
| | U+00a1 … U+1fff |
|
| | U+2000 … U+200a |
od wersji DEX 040 |
| | U+2010 … U+2027 |
|
| | U+202f |
od wersji DEX 040 |
| | U+2030 … U+d7ff |
|
| | U+e000 … U+ffef |
|
| | U+10000 … U+10ffff |
MemberName
używany przez field_id_item i method_id_item
NazwaCzłonka to nazwa elementu klasy, którym mogą być pola, metody i klasy wewnętrzne.
NazwaCzłonka → | |
SimpleName | |
| | '<' SimpleName '>' |
FullClassName
Pełna nazwa klasy to pełna nazwa klasy, w tym opcjonalny specyfikator pakietu, po którym następuje wymagana nazwa.
FullClassName → | |
OptionalPackagePrefix SimpleName | |
OptionalPackagePrefix → | |
(SimpleName '/' )* |
TypeDescriptor
Używany przez type_id_item
TypeDescriptor to reprezentacja dowolnego typu, w tym typów prymitywnych, klas, tablic i void
. Poniżej znajdziesz wyjaśnienie różnych wersji.
TypeDescriptor → | |
'V' |
|
| | FieldTypeDescriptor |
FieldTypeDescriptor → | |
NonArrayFieldTypeDescriptor | |
| | ('[' * 1…255)
NonArrayFieldTypeDescriptor |
NonArrayFieldTypeDescriptor→ | |
'Z' |
|
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' FullClassName ';' |
ShortyDescriptor
Używany przez proto_id_item
ShortyDescriptor to krótka reprezentacja prototypu metody, w tym typów zwracanych wartości i parametrów, z tym że nie ma rozróżnienia między różnymi typami referencji (klasy lub tablicy). Zamiast tego wszystkie typy odwołań są reprezentowane przez pojedynczy znak 'L'
.
ShortyDescriptor → | |
ShortyReturnType (ShortyFieldType)* | |
ShortyReturnType → | |
'V' |
|
| | ShortyFieldType |
ShortyFieldType → | |
'Z' |
|
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' |
Semantyka typu opisu
Oto znaczenie każdej z wariantów TypeDescriptor.
Składnia | Znaczenie |
---|---|
V | void ; dotyczy tylko typów zwrotów |
Z | boolean |
B | byte |
S | short |
C | char |
I | int |
J | long |
F | float |
D | double |
Lpełna/kwalifikowana nazwa; | zajęcia fully.qualified.Name |
[descriptor | tablica descriptor , która może być używana rekurencyjnie w przypadku tablic tablic, ale nie może mieć więcej niż 255 wymiarów.
|
Elementy i powiązane struktury
Ta sekcja zawiera definicje wszystkich elementów najwyższego poziomu, które mogą występować w pliku .dex
.
header_item
Wyświetla się w sekcji nagłówka
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
magia | ubyte[8] = DEX_FILE_MAGIC | magic value. Więcej informacji znajdziesz w sekcji „DEX_FILE_MAGIC ” powyżej.
|
suma kontrolna | uint | suma kontrolna adler32 reszty pliku (wszystko oprócz magic i tego pola); służy do wykrywania uszkodzeń pliku
|
podpis | ubyte[20] | podpis SHA-1 (skrót) reszty pliku (wszystko oprócz
magic , checksum i tego pola); służy do jednoznacznej identyfikacji plików
|
file_size | uint |
rozmiar całego pliku (w tym nagłówka) w bajtach (w wersji 40 lub wcześniejszej) odległość w bajtach od początku tego nagłówka do następnego nagłówka lub do końca całego pliku (kontenera). (w wersji 41 lub nowszej) |
header_size | uint |
rozmiar nagłówka (całej tej sekcji) w bajtach. Dzięki temu można uzyskać co najmniej ograniczoną zgodność wsteczną i do przodu bez unieważniania formatu. musi wynosić 0x70 (112) bajtów(wersja 40 lub starsza) musi wynosić 0x78 (120) bajtów(wersja 41 lub nowsza) |
endian_tag | uint = ENDIAN_CONSTANT | tag określający kolejność bajtów. Więcej informacji znajdziesz w sekcji „ENDIAN_CONSTANT
and REVERSE_ENDIAN_CONSTANT ”.
|
link_size | uint | rozmiar sekcji linku lub 0 , jeśli ten plik nie jest połączony statycznie |
link_off | uint | przesunięcie od początku pliku do sekcji linku lub 0 , jeśli link_size == 0 . Przesunięcie, jeśli jest różne od zera,
powinno być przesunięciem w sekcji link_data . Format danych, do których odwołuje się nagłówek, nie jest określony w tym dokumencie. To pole nagłówka (i poprzednie) jest przeznaczone do użycia przez implementacje w czasie wykonywania.
|
map_off | uint | przesunięcie od początku pliku do elementu mapy. Odchylenie, które musi być niezerowe, powinno być odchyleniem w sekcji data , a dane powinny być w formacie określonym przez „map_list ” poniżej.
|
string_ids_size | uint | liczba ciągów znaków na liście identyfikatorów ciągów znaków |
string_ids_off | uint | przesunięcie od początku pliku do listy identyfikatorów ciągu znaków lub 0 , jeśli string_ids_size == 0 (co jest dość dziwnym przypadkiem). Przesunięcie, jeśli nie jest równe 0, powinno być przesunięciem na początek sekcji string_ids .
|
type_ids_size | uint | liczba elementów na liście identyfikatorów typu, maksymalnie 65535 |
type_ids_off | uint | przesunięcie od początku pliku do listy identyfikatorów typów lub 0 , jeśli type_ids_size == 0 (co jest dość dziwnym przypadkiem). Przesunięcie, jeśli nie jest równe 0, powinno być przesunięte do początku sekcji type_ids .
|
proto_ids_size | uint | liczba elementów na liście identyfikatorów prototypów, maksymalnie 65 535 |
proto_ids_off | uint | przesunięcie od początku pliku do listy identyfikatorów prototypu lub 0 , jeśli proto_ids_size == 0 (co jest dość dziwnym przypadkiem). Przesunięcie, jeśli nie jest równe 0, powinno być przesunięte do początku sekcji proto_ids .
|
field_ids_size | uint | liczba elementów na liście identyfikatorów pól, |
field_ids_off | uint | przesunięcie od początku pliku do listy identyfikatorów pól lub 0 , jeśli field_ids_size == 0 . Odsunięcie, jeśli nie jest równe 0, powinno być przesunięte do początku sekcji field_ids . |
method_ids_size | uint | liczba elementów na liście identyfikatorów metody, |
method_ids_off | uint | przesunięcie od początku pliku do listy identyfikatorów metody lub 0 , jeśli method_ids_size == 0 . Odsunięcie, jeśli nie jest równe 0, powinno być przesunięte do początku sekcji method_ids . |
class_defs_size | uint | liczba elementów na liście definicji klas |
class_defs_off | uint | przesunięcie od początku pliku do listy definicji klas, lub
0 , jeśli class_defs_size == 0 (co jest dziwnym przypadkiem szczególnym). Przesunięcie, jeśli nie jest równe 0, powinno być przesunięciem na początek sekcji class_defs .
|
data_size | uint |
Rozmiar sekcji Nieużywane (wersja 41 lub nowsza) |
data_off | uint |
przesunięcie od początku pliku do początku sekcji Nieużywane (wersja 41 lub nowsza) |
container_size | uint |
to pole nie istnieje. Można założyć, że jest ona równa rozmiar całego pliku (w tym inne nagłówki dex i ich dane). (w wersji 41 lub nowszej) |
header_offset | uint |
to pole nie istnieje. Można założyć, że jest ona równa przesunięcie od początku pliku do początku tego nagłówka. (w wersji 41 lub nowszej) |
map_list
Występuje w sekcji danych
Odwołanie z header_item
Wyrównanie: 4 bajty
To lista całej zawartości pliku w kolejności. Zawiera ona pewne elementy zbędne w porównaniu z header_item
, ale ma być łatwa w użyciu i przeszukiwać cały plik. dany typ musi pojawić się w mapie najwyżej raz, ale nie ma ograniczeń dotyczących tego, w jakich typach zamówień może się on pojawiać, z wyjątkiem ograniczeń wynikających z reszty formatu (np. sekcja header
musi pojawić się jako pierwsza, a potem sekcja string_ids
itd.). Dodatkowo wpisy mapy muszą być posortowane według początkowego przesunięcia i nie mogą się nakładać.
Nazwa | Format | Opis |
---|---|---|
rozmiar | uint | rozmiar listy (liczba wpisów). |
lista | map_item[size] | elementów listy |
Format map_item
Nazwa | Format | Opis |
---|---|---|
typ | ushort | typ elementów (patrz tabela poniżej) |
unused | ushort | (nieużywany) |
rozmiar | uint | liczba elementów do znalezienia w współrzędnych wskazanych przez przesunięcie; |
przesunięcie | uint | przesunięcie od początku pliku do odpowiednich elementów. |
Kody typu
Typ elementu | Stała | Wartość | Rozmiar elementu w bajtach |
---|---|---|---|
header_item | TYPE_HEADER_ITEM | 0x0000 | 0x70 |
string_id_item | TYPE_STRING_ID_ITEM | 0x0001 | 0x04 |
type_id_item | TYPE_TYPE_ID_ITEM | 0x0002 | 0x04 |
proto_id_item | TYPE_PROTO_ID_ITEM | 0x0003 | 0x0c |
field_id_item | TYPE_FIELD_ID_ITEM | 0x0004 | 0x08 |
method_id_item | TYPE_METHOD_ID_ITEM | 0x0005 | 0x08 |
class_def_item | TYPE_CLASS_DEF_ITEM | 0x0006 | 0x20 |
call_site_id_item | TYPE_CALL_SITE_ID_ITEM | 0x0007 | 0x04 |
method_handle_item | TYPE_METHOD_HANDLE_ITEM | 0x0008 | 0x08 |
map_list | TYPE_MAP_LIST | 0x1000 | 4 + (item.size * 12) |
type_list | TYPE_TYPE_LIST | 0x1001 | 4 + (item.size * 2) |
annotation_set_ref_list | TYPE_ANNOTATION_SET_REF_LIST | 0x1002 | 4 + (item.size * 4) |
annotation_set_item | TYPE_ANNOTATION_SET_ITEM | 0x1003 | 4 + (item.size * 4) |
class_data_item | TYPE_CLASS_DATA_ITEM | 0x2000 | implicit; must parse |
code_item | TYPE_CODE_ITEM | 0x2001 | implicit; must parse |
string_data_item | TYPE_STRING_DATA_ITEM | 0x2002 | implicit; must parse |
debug_info_item | TYPE_DEBUG_INFO_ITEM | 0x2003 | implicit; must parse |
annotation_item | TYPE_ANNOTATION_ITEM | 0x2004 | implicit; must parse |
encoded_array_item | TYPE_ENCODED_ARRAY_ITEM | 0x2005 | implicit; must parse |
annotations_directory_item | TYPE_ANNOTATIONS_DIRECTORY_ITEM | 0x2006 | implicit; must parse |
hiddenapi_class_data_item | TYPE_HIDDENAPI_CLASS_DATA_ITEM | 0xF000 | implicit; must parse |
string_id_item
Pojawia się w sekcji string_ids.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
string_data_off | uint | przesunięcie od początku pliku do danych ciągu dotyczących tego elementu. Odchylenie powinno odnosić się do lokalizacji w sekcji data , a dane powinny być w formacie określonym przez „string_data_item ” poniżej.
Nie ma wymagań dotyczących wyrównania przesunięcia.
|
string_data_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Nazwa | Format | Opis |
---|---|---|
utf16_size | uleb128 | rozmiar tego ciągu znaków w jednostkach kodu UTF-16 (co w wielu systemach jest „długością ciągu znaków”); Jest to dekodowana długość ciągu. (zakodowana długość jest sugerowana przez pozycję bajtu 0 ). |
dane | ubyte[] | seria jednostek kodu MUTF-8 (czyli oktetów lub bajtów), po której następuje bajt o wartości 0 . Szczegółowe informacje o tym formacie danych oraz omówienie go znajdziesz w sekcji „Kodowanie MUTF-8 (zmodyfikowany UTF-8)” powyżej.
Uwaga: dopuszczalne jest użycie ciągu znaków zawierającego jednostki kodu zastępczego UTF-16 (czyli |
type_id_item
Występuje w sekcji type_ids.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
descriptor_idx | uint | indeksowanie listy string_ids w przypadku ciągu znaków opisowego tego typu; Ciąg musi być zgodny ze składnią TypDescriptor zdefiniowaną powyżej.
|
proto_id_item
Występuje w sekcji proto_ids
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
shorty_idx | uint | indeks na liście string_ids dla krótkiego ciągu znaków w charakterystyce tego prototypu. Ciąg znaków musi być zgodny z syntaksą ShortyDescriptor zdefiniowaną powyżej i musi odpowiadać typowi zwracanych danych oraz parametrom tego elementu.
|
return_type_idx | uint | indeks na liście type_ids dla typu zwracanego przez ten prototyp
|
parameters_off | uint | przesunięcie od początku pliku do listy typów parametrów tego prototypu lub 0 , jeśli prototyp nie ma parametrów. Ten przesunięcie, jeśli jest inne niż zero, powinno znajdować się w sekcji
data , a dane w tej sekcji powinny być w formacie określonym przez parametr "type_list" poniżej. Dodatkowo na liście nie powinno być żadnych odwołań do typu void .
|
field_id_item
Występuje w sekcji field_ids.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
class_idx | ushort | indeks do listy type_ids definiującej to pole. Musi to być typ klasy, a nie tablica ani typ prymitywny.
|
type_idx | ushort | indeksowanie listy type_ids pod kątem typu tego pola;
|
name_idx | uint | indeks w liście string_ids odpowiadający nazwie tego pola. Ciąg znaków musi być zgodny ze składnią parametru MemberName zdefiniowanego powyżej.
|
method_id_item
Występuje w sekcji method_ids.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
class_idx | ushort | indeks na liście type_ids definicji tej metody. Musi to być typ klasy lub tablicy, a nie typ prymitywny.
|
proto_idx | ushort | indeks na liście proto_ids dla prototypu tej metody
|
name_idx | uint | indeks w liście string_ids zawierający nazwę tej metody. Ciąg znaków musi być zgodny ze składnią parametru MemberName zdefiniowanego powyżej.
|
class_def_item
Pojawia się w sekcji class_defs.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
class_idx | uint | indeks na liście type_ids dla tej klasy.
Musi to być typ klasy, a nie tablica ani typ prymitywny.
|
access_flags | uint | flagi dostępu do zajęć (public , final itd.). Więcej informacji znajdziesz w sekcji „access_flags Definicje”.
|
superclass_idx | uint | indeks w liście type_ids dla superklasy lub stałą wartość NO_INDEX , jeśli ta klasa nie ma superklasy (czyli jest to klasa rdzenna, np. Object ). Jeśli jest obecna, musi być typem klasy, a nie tablicą ani typem prymitywnym.
|
interfaces_off | uint | przesunięcie od początku pliku do listy interfejsów lub 0 , jeśli ich nie ma. Ten przesunięcie powinno znajdować się w sekcji data , a dane w niej powinny być w formacie określonym przez parametr „type_list ” poniżej. Każdy element listy musi być typem klasy (nie tablicą ani typem prymitywnym) i nie może być duplikatem.
|
source_file_idx | uint | indeks na liście string_ids dla nazwy pliku zawierającego pierwotne źródło (przynajmniej w większości) tej klasy lub wartość specjalna NO_INDEX oznaczająca brak tych informacji. debug_info_item dowolnej metody może zastąpić ten plik źródłowy, ale zakłada się, że większość klas będzie pochodzić tylko z jednego pliku źródłowego.
|
annotations_off | uint | przesunięcie od początku pliku do struktury adnotacji dla tych zajęć lub 0 , jeśli w przypadku tych zajęć nie ma adnotacji. Ten przesunięcie, jeśli jest różne od zera, powinno znajdować się w sekcji data , a dane w niej powinny być w formacie określonym w sekcji „annotations_directory_item ” poniżej, przy czym wszystkie elementy odwołują się do tej klasy jako definiującej.
|
class_data_off | uint | przesunięcie od początku pliku do powiązanych danych klasy dla tego elementu lub 0 , jeśli dla tej klasy nie ma danych. (może się tak zdarzyć, jeśli ta klasa jest interfejsem znacznika). Odsunięcie, jeśli jest różne od 0, powinno znajdować się w sekcji
data , a dane w niej powinny być w formacie określonym przez „class_data_item ” poniżej, przy czym wszystkie elementy odnoszą się do tej klasy jako definiującej.
|
static_values_off | uint | przesunięcie od początku pliku do listy początkowych wartości pól static lub 0 , jeśli ich nie ma (wszystkie pola static mają być inicjowane wartościami 0 lub null ). To przesunięcie powinno znajdować się w sekcji data , a dane w tym miejscu powinny być w formacie określonym przez „encoded_array_item ” poniżej. Rozmiar tablicy nie może być większy niż liczba pól static zadeklarowanych przez tę klasę, a elementy odpowiadają polom static w tej samej kolejności, w jakiej zostały zadeklarowane w odpowiednim elemencie field_list . Typ każdego elementu tablicy musi być zgodny z deklarowanym typem odpowiadającego mu pola.
Jeśli w tablicy jest mniej elementów niż pól static , pozostałe pola są inicjowane wartościami 0 lub null odpowiednimi do typu.
|
call_site_id_item
Pojawia się w sekcji call_site_ids.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
call_site_off | uint | przesunięcie od początku pliku do definicji strony wywołania. Odsunięcie powinno znajdować się w sekcji danych, a dane w niej powinny być w formacie określonym przez element „call_site_item” poniżej. |
call_site_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Element call_site_item to element encoded_array_item, którego elementy odpowiadają argumentom przekazanym metodzie bootstrap linker. Pierwsze 3 argumenty to:
- Identyfikator metody reprezentujący metodę łącznika bootstrap (VALUE_METHOD_HANDLE).
- Nazwa metody, którą linker bootstrap powinien rozwiązać (VALUE_STRING).
- Typ metody odpowiadający typowi nazwy metody do rozwiązania (VALUE_METHOD_TYPE).
Wszystkie dodatkowe argumenty to stałe wartości przekazywane do metody łącznika bootstrap. Te argumenty są przekazywane w kolejności bez konwersji typu.
Identyfikator metody reprezentujący metodę łącznika bootstrap musi mieć typ zwracania java.lang.invoke.CallSite
. Pierwsze 3 typy parametrów to:
java.lang.invoke.Lookup
java.lang.String
java.lang.invoke.MethodType
Typy parametrów wszystkich dodatkowych argumentów są określane na podstawie ich stałych wartości.
method_handle_item
Występuje w sekcji method_handles.
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
method_handle_type | ushort | typ uchwytu metody (patrz tabela poniżej) |
unused | ushort | (nieużywany) |
field_or_method_id | ushort | identyfikator pola lub metody w zależności od tego, czy typ uchwytu metody jest akcesorem czy wywoływaczem metody; |
unused | ushort | (nieużywany) |
Kody typu uchwytu metody
Stała | Wartość | Opis |
---|---|---|
METHOD_HANDLE_TYPE_STATIC_PUT | 0x00 | uchwyt metody to ustawiacz stałego pola (akcesor) |
METHOD_HANDLE_TYPE_STATIC_GET | 0x01 | uchwyt metody to statycznego pola gettera (akcesora) |
METHOD_HANDLE_TYPE_INSTANCE_PUT | 0x02 | uchwyt metody to ustawiacz pola instancji (akcesor); |
METHOD_HANDLE_TYPE_INSTANCE_GET | 0x03 | uchwyt metody to metoda pobierająca wartości pola instancji (akcesor) |
METHOD_HANDLE_TYPE_INVOKE_STATIC | 0x04 | uchwyt metody to wywoływacz metody statycznej |
METHOD_HANDLE_TYPE_INVOKE_INSTANCE | 0x05 | uchwyt metody to wywoływacz metody instancji |
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR | 0x06 | uchwyt metody to wywoływacz metody konstruktora |
METHOD_HANDLE_TYPE_INVOKE_DIRECT | 0x07 | Uchwyt metody to bezpośredni wywoływacz metody |
METHOD_HANDLE_TYPE_INVOKE_INTERFACE | 0x08 | Identyfikator metody to wywoływacz metody interfejsu |
class_data_item
Odwołanie z class_def_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Nazwa | Format | Opis |
---|---|---|
static_fields_size | uleb128 | liczba pól statycznych zdefiniowanych w tym elemencie. |
instance_fields_size | uleb128 | liczba pól instancji zdefiniowanych w tym elemencie |
direct_methods_size | uleb128 | liczba metod bezpośrednich zdefiniowanych w tym elemencie |
virtual_methods_size | uleb128 | liczba metod wirtualnych zdefiniowanych w tym elemencie |
static_fields | encoded_field[static_fields_size] | zdefiniowane pola statyczne, reprezentowane jako sekwencja zakodowanych elementów; Pola muszą być posortowane według kolumny field_idx w kolejności rosnącej.
|
instance_fields | encoded_field[instance_fields_size] | zdefiniowane pola instancji, reprezentowane jako sekwencja zakodowanych elementów. Pola muszą być posortowane według kolumny field_idx w kolejności rosnącej.
|
direct_methods | encoded_method[direct_methods_size] | zdefiniowane metody bezpośrednie (dowolna z metod static , private lub konstruktora), reprezentowane jako sekwencja zakodowanych elementów. Metody muszą być posortowane według kolumny method_idx w kolejności rosnącej.
|
virtual_methods | encoded_method[virtual_methods_size] | zdefiniowane metody wirtualne (inne niż static , private lub konstruktor), reprezentowane jako sekwencja zakodowanych elementów. Ta lista nie powinna zawierać metod dziedziczonych, chyba że zostały zastąpione przez klasę, którą reprezentuje dany element. Metody muszą być posortowane według method_idx w kolejności rosnącej.
method_idx metody wirtualnej nie może być taki sam jak w przypadku dowolnej metody bezpośredniej.
|
Uwaga: wszystkie wystąpienia elementów field_id
i method_id
muszą odwoływać się do tej samej klasy definiującej.
Format encoded_field
Nazwa | Format | Opis |
---|---|---|
field_idx_diff | uleb128 | indeks na liście field_ids odpowiadający tożsamości tego pola (zawiera nazwę i opis), reprezentowany jako różnica względem indeksu poprzedniego elementu na liście. Indeks pierwszego elementu na liście jest reprezentowany bezpośrednio.
|
access_flags | uleb128 | flagi dostępu do pola (public , final itd.). Więcej informacji znajdziesz w sekcji „access_flags Definicje”.
|
Format encoded_method
Nazwa | Format | Opis |
---|---|---|
method_idx_diff | uleb128 | indeks na liście method_ids identyfikujący tę metodę (zawiera nazwę i opis), reprezentowany jako różnica względem indeksu poprzedniego elementu na liście. Indeks pierwszego elementu na liście jest reprezentowany bezpośrednio.
|
access_flags | uleb128 | flagi dostępu metody (public , final itd.). Więcej informacji znajdziesz w sekcji „access_flags Definicje”.
|
code_off | uleb128 | przesunięcie od początku pliku do struktury kodu tej metody lub 0 , jeśli ta metoda to abstract lub native . Przesunięcie powinno dotyczyć lokalizacji w sekcji
data . Format danych jest określony przez „code_item ” poniżej.
|
type_list
Odwołuje się do class_def_item i proto_id_item
Występuje w sekcji danych
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
rozmiar | uint | rozmiar listy (liczba wpisów). |
lista | type_item[size] | elementów listy |
Format type_item
Nazwa | Format | Opis |
---|---|---|
type_idx | ushort | indeks na liście type_ids |
code_item
Odwołanie z encoded_method
Występuje w sekcji danych
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
registers_size | ushort | liczba rejestrów używanych przez ten kod; |
ins_size | ushort | liczba słów argumentów przychodzących do metody, do której odnosi się ten kod; |
outs_size | ushort | liczba słów w polu argumentu wyjściowego wymaganego przez ten kod do wywołania metody; |
tries_size | ushort | liczba try_item w tej instancji. Jeśli wartość jest różna od 0, w tym przypadku tries będzie równe tablicy insns .
|
debug_info_off | uint | przesunięcie od początku pliku do informacji debugowania (sekwencja informacji o numerach wierszy + informacje o lokalnych zmiennych) dla tego kodu albo 0 , jeśli nie ma żadnych informacji. Odsunięcie (jeśli nie jest równe 0) powinno być równe lokalizacji w sekcji data . Format danych jest określony przez „debug_info_item ” poniżej.
|
insns_size | uint | rozmiar listy instrukcji w jednostkach kodu 16-bitowego; |
insns | ushort[insns_size] | rzeczywiste tablice kodu bajtowego. Format kodu w tablicy insns jest określony w dokumentacji towarzyszącej bajtkodowi Dalvik. Pamiętaj, że chociaż ta tablica jest zdefiniowana jako tablica typu ushort , to istnieją pewne wewnętrzne struktury, które preferują wyrównanie do 4 bajtów. Jeśli plik ma odwróconą kolejność bajtów, zamiana zostanie przeprowadzona tylko w przypadku poszczególnych wystąpień ushort , a nie w większych strukturach wewnętrznych.
|
padding | ushort (opcjonalnie) = 0 | 2 bajty wypełniające, aby tries był wyrównany co 4 bajty.
Ten element jest widoczny tylko wtedy, gdy tries_size jest niezerowy, a insns_size jest nieparzysty.
|
próby | try_item[tries_size] (opcjonalnie) | tablicy wskazującej, gdzie w programie występują wyjątki oraz jak je obsługiwać. Elementy tablicy nie mogą się pokrywać w zakresie i muszą być uporządkowane od najniższych do najwyższych adresów. Ten element jest obecny tylko wtedy, gdy tries_size jest niezerowy.
|
moduły obsługi | encoded_catch_handler_list (opcjonalnie) | bajtów reprezentujących listę list typów łapania i powiązanych adresów przetwarzających. Każdy element try_item ma przesunięcie bajtowe w tej strukturze. Ten element jest obecny tylko wtedy, gdy tries_size jest niezerowy.
|
Format try_item
Nazwa | Format | Opis |
---|---|---|
start_addr | uint | adres początkowy bloku kodu objętego tą pozycją. Adres jest liczbą 16-bitowych jednostek kodu do początku pierwszej instrukcji objętej tym adresem. |
insn_count | ushort | liczba 16-bitowych jednostek kodu objętych tym wpisem. Ostatni kod
jednostka objęta (włącznie) to start_addr + insn_count - 1 .
|
handler_off | ushort | przesunięcie w bajtach od początku powiązanego elementu
encoded_catch_hander_list do
encoded_catch_handler dla tego wpisu. Musi być przesunięty względem początku encoded_catch_handler .
|
Format encoded_catch_handler_list
Nazwa | Format | Opis |
---|---|---|
rozmiar | uleb128 | rozmiar tej listy (liczba wpisów). |
lista | encoded_catch_handler[handlers_size] | rzeczywista lista list elementów obsługi, reprezentowana bezpośrednio (nie jako przesunięcia), a następnie połączona sekwencyjnie |
Format encoded_catch_handler
Nazwa | Format | Opis |
---|---|---|
rozmiar | sleb128 | liczba typów połowów na tej liście. Jeśli nie jest dodatnia, jest ujemną wartością liczby typów łapacza, a łapacze są poprzedzone przez ogólny przetwarzacz. Na przykład: size z 0 oznacza, że istnieje uniwersalny typ, ale nie ma żadnych typów z wyraźnie określonymi regułami.
size z 2 oznacza, że są 2 explicitly typed catches i brak catch-all. A size z -1 oznacza, że jest jeden typowany element i element uniwersalny.
|
moduły obsługi | encoded_type_addr_pair[abs(size)] | strumień zakodowanych elementów abs(size) , po jednym dla każdego typu, w kolejności, w jakiej te typy powinny być testowane.
|
catch_all_addr | uleb128 (opcjonalnie) | adres bajtowy obsługi typu catch-all. Ten element jest obecny tylko wtedy, gdy size ma wartość niezerową.
|
Format encoded_type_addr_pair
Nazwa | Format | Opis |
---|---|---|
type_idx | uleb128 | indeks na liście type_ids odpowiadający typowi wyjątku do przechwycenia
|
addr | uleb128 | adres bajtowy powiązanego modułu obsługi wyjątków. |
debug_info_item
Odwołanie z poziomu kodu_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Każda wartość debug_info_item
definiuje maszynę stanów kodowaną bajtami, która jest inspirowana DWARF3. Po interpretacji emituje tablicę pozycji i (opcjonalnie) informacje o zmiennych lokalnych dla code_item
. Sekwencja zaczyna się nagłówkiem o zmiennej długości (długość zależy od liczby parametrów metody), po którym następują bajty kodu bajtowego maszyny stanów, a kończy się bajtem DBG_END_SEQUENCE
.
Maszyna stanów składa się z 5 rejestrów. Rejestr address
reprezentuje przesunięcie instrukcji w powiązanym insns_item
w 16-bitowych jednostkach kodu. Rejestr address
zaczyna się od wartości 0
na początku każdej sekwencji debug_info
i musi monotonicznie rosnąć.
Rejestr line
wskazuje, który numer wiersza źródła powinien być powiązany z kolejną pozycją w tabeli generowanej przez maszynę stanów. Jest on inicjowany w nagłówku sekwencji i może się zmieniać w kierunku dodatnim lub ujemnym, ale nigdy nie może być mniejszy niż 1
. Rejestr source_file
to plik źródłowy, do którego odnoszą się wpisy numeru wiersza. Jest on inicjowany wartością source_file_idx
w class_def_item
.
Pozostałe 2 zmiennych, prologue_end
i epilogue_begin
, to flagi logiczne (inicjowane jako false
), które wskazują, czy emitowana pozycja ma być uważana za prolog czy epilog metody. Maszyna stanów musi też śledzić nazwę i typ ostatniej zmiennej lokalnej w każdym rejestrze kodu DBG_RESTART_LOCAL
.
Nagłówek wygląda tak:
Nazwa | Format | Opis |
---|---|---|
line_start | uleb128 | początkowa wartość rejestru line maszyny stanów.
Nie reprezentuje rzeczywistego wpisu pozycji.
|
parameters_size | uleb128 | liczba zakodowanych nazw parametrów. Należy utworzyć po jednym dla każdego parametru metody, z wyjątkiem parametru this metody instancji, jeśli taki występuje.
|
parameter_names | uleb128p1[parameters_size] | indeks ciągu znaków nazwy parametru metody. Zaszyfrowana wartość NO_INDEX oznacza, że nie ma nazwy dostępnej dla powiązanego parametru. Opis typu i podpis są implikowane z opisu metody i podpisu.
|
Wartości kodu bajtowego:
Nazwa | Wartość | Format | Argumenty | Opis |
---|---|---|---|---|
DBG_END_SEQUENCE | 0x00 | (brak) | kończy sekwencję danych debugowania w przypadku code_item |
|
DBG_ADVANCE_PC | 0x01 | uleb128 addr_diff | addr_diff : kwota do dodania do rejestru adresów |
przesuwa rejestr adresów bez emitowania pozycji |
DBG_ADVANCE_LINE | 0x02 | sleb128 line_diff | line_diff : kwota, o jaką ma się zmienić rejestr linii |
przesuwa rejestr linii bez emitowania pozycji |
DBG_START_LOCAL | 0x03 | uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx |
register_num : rejestr, który będzie zawierać lokalną zmiennąname_idx : indeks ciągu znaków nazwytype_idx : indeks typu
|
wprowadza zmienną lokalną w bieżącym adresie. Możesz użyć wartości name_idx lub type_idx , aby wskazać, że ta wartość jest nieznana.NO_INDEX
|
DBG_START_LOCAL_EXTENDED | 0x04 | uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx uleb128p1 sig_idx |
register_num : rejestr, który będzie zawierać lokalną wartośćname_idx : indeks ciągu znaków nazwytype_idx : indeks typusig_idx : indeks ciągu znaków sygnatury typu
|
wprowadza lokalny typ z podpisem w bieżącym adresie.
Wartość name_idx , type_idx lub sig_idx może być NO_INDEX , aby wskazać, że wartość jest nieznana. (Jeśli sig_idx jest
-1 , te same dane można przedstawić bardziej efektywnie za pomocą kodu operacji DBG_START_LOCAL ).
Uwaga: poniżej w sekcji „ |
DBG_END_LOCAL | 0x05 | uleb128 register_num | register_num : rejestr zawierający lokalny |
oznacza bieżącą zmienną lokalną jako nieobejmowaną przez bieżący adres; |
DBG_RESTART_LOCAL | 0x06 | uleb128 register_num | register_num : zarejestruj się, aby ponownie uruchomić |
ponownie wprowadza lokalną zmienną w bieżącym adresie. Nazwa i typ są takie same jak w ostatnim lokalnym rekordzie w określonym rejestrze. |
DBG_SET_PROLOGUE_END | 0x07 | (brak) | ustawia rejestr maszyny stanów prologue_end , wskazując, że dodana pozycja następna powinna być traktowana jako koniec prologu metody (odpowiednie miejsce na punkt przerwania metody). Rejester prologue_end jestczyszczany przez dowolny kod operacji specjalnej (>= 0x0a ).
|
|
DBG_SET_EPILOGUE_BEGIN | 0x08 | (brak) | ustawia rejestr maszyny stanów epilogue_begin ,
wskazując, że dodany następny wpis pozycji powinien być
traktowany jako początek epilogu metody (odpowiednie miejsce
do zawieszenia wykonania przed wyjściem z metody).
Rejestr epilogue_begin jest opróżniany przez dowolny kod operacji specjalnej (>= 0x0a ).
|
|
DBG_SET_FILE | 0x09 | uleb128p1 name_idx | name_idx : indeks ciągu znaków nazwy pliku źródłowego;
NO_INDEX , jeśli jest nieznany
|
oznacza, że wszystkie kolejne wpisy numeru wiersza odwołują się do tej nazwy pliku źródłowego, a nie do nazwy domyślnej określonej w pliku code_item
|
Kody operacji specjalne | 0x0a…0xff | (brak) | przesuwa rejestry line i address ,
wysyła wpis pozycji oraz czyści prologue_end i epilogue_begin . Opis znajdziesz poniżej.
|
Specjalne kody operacji
Kody operacji o wartościach od 0x0a
do 0xff
(łącznie) przesuwają rejestry line
i address
o niewielką wartość, a następnie emitują nowy wpis w tabeli pozycji.
Formuła przyrostów:
DBG_FIRST_SPECIAL = 0x0a // the smallest special opcode DBG_LINE_BASE = -4 // the smallest line number increment DBG_LINE_RANGE = 15 // the number of line increments represented adjusted_opcode = opcode - DBG_FIRST_SPECIAL line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE) address += (adjusted_opcode / DBG_LINE_RANGE)
annotations_directory_item
Odwołanie z class_def_item
Występuje w sekcji danych
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
class_annotations_off | uint | przesunięcie od początku pliku do adnotacji wprowadzonych bezpośrednio w klasie lub 0 , jeśli klasa nie zawiera adnotacji bezpośrednich.
Odsunięcie, jeśli nie jest równe 0, powinno wskazywać lokalizację w sekcji
data . Format danych jest określony przez „annotation_set_item ” poniżej.
|
fields_size | uint | liczba pól oznaczonych przez ten element |
annotated_methods_size | uint | liczba metod oznaczonych przez ten element |
annotated_parameters_size | uint | liczba list parametrów metody oznaczonych przez ten element |
field_annotations | field_annotation[fields_size] (opcjonalnie) | lista powiązanych adnotacji pól. Elementy listy muszą być posortowane w kolejności rosnącej według kolumny field_idx .
|
method_annotations | method_annotation[methods_size] (opcjonalnie) | lista powiązanych adnotacji metody. Elementy listy muszą być posortowane w kolejności rosnącej według kolumny method_idx .
|
parameter_annotations | parameter_annotation[parameters_size] (opcjonalnie) | lista powiązanych adnotacji parametrów metody; Elementy listy muszą być posortowane w kolejności rosnącej według kolumny method_idx .
|
Uwaga: wszystkie wystąpienia elementów field_id
i method_id
muszą odwoływać się do tej samej klasy definiującej.
format field_annotation
Nazwa | Format | Opis |
---|---|---|
field_idx | uint | indeks na liście field_ids odpowiadający tożsamości pola, które ma być opatrzone adnotacją;
|
annotations_off | uint | przesunięcie od początku pliku do listy adnotacji dla tego pola. Przesunięcie powinno być ustawione na lokalizację w sekcji data . Format danych jest określony przez „annotation_set_item ” poniżej.
|
format method_annotation
Nazwa | Format | Opis |
---|---|---|
method_idx | uint | indeks w liście method_ids zawierający tożsamość metody, której dotyczy adnotacja;
|
annotations_off | uint | przesunięcie od początku pliku do listy adnotacji dla metody. Przesunięcie powinno dotyczyć lokalizacji w sekcji
data . Format danych jest określony przez „annotation_set_item ” poniżej.
|
Format parameter_annotation
Nazwa | Format | Opis |
---|---|---|
method_idx | uint | indeks w liście method_ids odpowiadający metodzie, której parametry są adnotowane
|
annotations_off | uint | przesunięcie od początku pliku do listy adnotacji dla parametrów metody. Przesunięcie powinno dotyczyć lokalizacji w sekcji
data . Format danych jest określony przez „annotation_set_ref_list ” poniżej.
|
annotation_set_ref_list
Odwołanie z elementu parameter_annotations_item
Występuje w sekcji danych
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
rozmiar | uint | rozmiar listy (liczba wpisów). |
lista | annotation_set_ref_item[size] | elementów listy |
Format annotation_set_ref_item
Nazwa | Format | Opis |
---|---|---|
annotations_off | uint | przesunięcie od początku pliku do zestawu adnotacji, na który się odwołuje
lub 0 , jeśli nie ma adnotacji dla tego elementu.
Jeśli przesunięcie jest inne niż zero, powinno wskazywać lokalizację w sekcji data . Format danych jest określony przez „annotation_set_item ” poniżej.
|
annotation_set_item
Odwołuje się do elementów annotations_directory_item, field_annotations_item, method_annotations_item i annotation_set_ref_item.
Występuje w sekcji danych
Wyrównanie: 4 bajty
Nazwa | Format | Opis |
---|---|---|
rozmiar | uint | rozmiar zbioru (liczba wpisów). |
wpisy | annotation_off_item[size] | elementów zestawu. Elementy muszą być posortowane w kolejności rosnącej według kolumny type_idx .
|
Format annotation_off_item
Nazwa | Format | Opis |
---|---|---|
annotation_off | uint | przesunięcie od początku pliku do adnotacji.
Odchylenie powinno odnosić się do lokalizacji w sekcji data , a format danych w tej lokalizacji jest określony przez parametr „annotation_item ” poniżej.
|
annotation_item
Odwołanie z annotation_set_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Nazwa | Format | Opis |
---|---|---|
widoczność | ubyte | zamierzona widoczność tej adnotacji (patrz poniżej); |
adnotacja | encoded_annotation | zakodowane treści adnotacji w formacie opisanym w sekcji „Format encoded_annotation ” w sekcji „Kodowanie encoded_value ” powyżej.
|
Wartości widoczności
Oto opcje pola visibility
w elementach annotation_item
:
Nazwa | Wartość | Opis |
---|---|---|
VISIBILITY_BUILD | 0x00 | mają być widoczne tylko w czasie kompilacji (np. podczas kompilowania innego kodu); |
VISIBILITY_RUNTIME | 0x01 | mają być widoczne w czasie wykonywania. |
VISIBILITY_SYSTEM | 0x02 | widoczne w czasie wykonywania, ale tylko dla systemu bazowego (a nie dla zwykłego kodu użytkownika); |
encoded_array_item
Odwołanie z class_def_item
Występuje w sekcji danych
Wyrównanie: brak (wyrównanie bajtowe)
Nazwa | Format | Opis |
---|---|---|
wartość | encoded_array | bajty reprezentujące zakodowaną wartość tablicy w formacie określonym przez „encoded_array Format” w sekcji „encoded_value
kodowanie” powyżej.
|
hiddenapi_class_data_item
Ta sekcja zawiera dane o interfejsach z ograniczonym dostępem używanych przez poszczególne klasy.
Uwaga: funkcja ukrytego interfejsu API została wprowadzona w Androidzie 10.0 i dotyczy tylko plików DEX klas na ścieżce uruchamiania. Lista flag opisanych poniżej może zostać rozszerzona w kolejnych wersjach Androida. Więcej informacji znajdziesz w artykule o ograniczeniach interfejsów innych niż SDK.
Nazwa | Format | Opis |
---|---|---|
rozmiar | uint | łączny rozmiar sekcji. |
przesunięcia | uint[] | tablica przesunięć indeksowana przez class_idx .
Wpis tablicy o wartości 0 w indeksie class_idx oznacza, że albo nie ma danych dla tego class_idx , albo wszystkie ukryte flagi interfejsu API mają wartość 0.
W przeciwnym razie wpis tablicy ma wartość różną od 0 i zawiera przesunięcie od początku sekcji do tablicy ukrytych flag interfejsu API dla tego class_idx .
|
flagi | uleb128[] | złączone tablice ukrytych flag interfejsu API dla każdej klasy. Możliwe wartości flagi zostały opisane w tabeli poniżej. Flagi są kodowane w tej samej kolejności, w jakiej pola i metody są kodowane w danych klasy. |
Typy flag ograniczeń:
Nazwa | Wartość | Opis |
---|---|---|
biała lista | 0 | Interfejsy, których można używać swobodnie i które są obsługiwane w ramach oficjalnie udokumentowanego frameworka Androida Package Index. |
szara lista | 1 | interfejsy spoza pakietu SDK, których można używać niezależnie od docelowego poziomu interfejsu API aplikacji; |
zablokuj | 2 | interfejsów spoza pakietu SDK, których nie można używać niezależnie od docelowego poziomu interfejsu API aplikacji; Uzyskanie dostępu do jednego z tych interfejsów powoduje błąd podczas działania. |
greylist‑max‑o | 3 | interfejsy spoza pakietu SDK, które można używać w przypadku Androida 8.x i starszych, chyba że są ograniczone; |
greylist‑max‑p | 4 | interfejsy spoza pakietu SDK, które można używać w Androidzie 9.x, chyba że są ograniczone; |
greylist‑max‑q | 5 | interfejsy spoza pakietu SDK, które można używać w Androidzie 10.x, chyba że są ograniczone; |
greylist‑max‑r | 6 | Interfejsy spoza pakietu SDK, których można używać w Androidzie 11.x, chyba że są ograniczone. |
Adnotacje systemowe
Adnotacje systemowe służą do reprezentowania różnych informacji o klasach (oraz metodach i polach). Te informacje są zazwyczaj dostępne tylko pośrednio przez kod klienta (niesystemowy).
Adnotacje systemowe są reprezentowane w plikach .dex
jako adnotacje z widocznością ustawioną na VISIBILITY_SYSTEM
.
dalvik.annotation.AnnotationDefault
Występuje w metodach w interfejsach adnotacji
Do każdego interfejsu adnotacji, który ma wskazywać domyślne wiązania, jest dołączona adnotacja AnnotationDefault
.
Nazwa | Format | Opis |
---|---|---|
wartość | Adnotacja | domyślne powiązania tej adnotacji, reprezentowane jako adnotacja tego typu. Adnotacja nie musi zawierać wszystkich nazw zdefiniowanych przez adnotację; brakujące nazwy po prostu nie mają wartości domyślnych. |
dalvik.annotation.EnclosingClass
Pojawia się na zajęciach
Do każdej klasy, która jest zdefiniowana jako element innej klasy lub jest anonimowa, ale nie jest zdefiniowana w ciele metody (np. syntetyczna klasa wewnętrzna), jest dołączona adnotacja EnclosingClass
. Każda klasa, która ma tę adnotację, musi mieć też adnotację InnerClass
. Dodatkowo zajęcia nie mogą mieć zarówno adnotacji EnclosingClass
, jak i EnclosingMethod
.
Nazwa | Format | Opis |
---|---|---|
wartość | Kategoria | klasa, która najbardziej pasuje do tej klasy pod względem leksykalnym |
dalvik.annotation.EnclosingMethod
Pojawia się na zajęciach
Do każdej klasy zdefiniowanej w ciele metody jest dołączona adnotacja EnclosingMethod
. Każda klasa, która ma tę adnotację, musi mieć też adnotację InnerClass
.
Dodatkowo zajęcia nie mogą mieć jednocześnie adnotacji EnclosingClass
i EnclosingMethod
.
Nazwa | Format | Opis |
---|---|---|
wartość | Metoda | metoda, która najlepiej określa zakres leksykalny tej klasy; |
dalvik.annotation.InnerClass
Pojawia się na zajęciach
Do każdej klasy, która jest zdefiniowana w zakresie leksykalnym definicji innej klasy, jest dołączona adnotacja InnerClass
.
Każda klasa, która ma tę adnotację, musi mieć adnotację EnclosingClass
lub adnotację EnclosingMethod
.
Nazwa | Format | Opis |
---|---|---|
nazwa | Ciąg znaków | pierwotnie zadeklarowana prosta nazwa tej klasy (bez prefiksu pakietu). Jeśli zajęcia są anonimowe, ich nazwa to null .
|
accessFlags | int | pierwotnie zadeklarowane flagi dostępu klasy (które mogą różnić się od flag skutecznych z powodu niezgodności modeli wykonania języka źródłowego i docelowej maszyny wirtualnej); |
dalvik.annotation.MemberClasses
Pojawia się na zajęciach
Do każdej klasy dołączona jest adnotacja MemberClasses
, która deklaruje klasy członkowskie. (Klasa członkowska jest klasą wewnętrzną bezpośrednio zawierającą nazwę).
Nazwa | Format | Opis |
---|---|---|
wartość | Class[] | tablica klas członków |
dalvik.annotation.MethodParameters
Pojawia się w metodach
Uwaga: ta adnotacja została dodana po Androidzie 7.1. Jego obecność w poprzednich wersjach Androida zostanie zignorowana.
Adnotacja MethodParameters
jest opcjonalna i może służyć do udostępniania metadanych parametrów, takich jak nazwy i modyfikatory parametrów.
Adnotację można bezpiecznie pominąć w metodzie lub konstruktorze, jeśli metadane parametru nie są wymagane w czasie wykonywania.
Za pomocą funkcji java.lang.reflect.Parameter.isNamePresent()
możesz sprawdzić, czy w przypadku danego parametru występują metadane. Jeśli nie, powiązane metody odbicia, takie jak java.lang.reflect.Parameter.getName()
, powrócą do domyślnego zachowania w czasie wykonywania.
W przypadku dołączania metadanych parametrów kompilatory muszą uwzględniać informacje o wygenerowanych klasach, takich jak enumy, ponieważ metadane parametrów obejmują informacje o tym, czy parametr jest syntetyczny, czy wymagany.
Adnotacja MethodParameters
opisuje tylko poszczególne parametry metody. Dlatego kompilatory mogą całkowicie pominąć adnotację w przypadku konstruktorów i metod bez parametrów, aby zmniejszyć rozmiar kodu i zwiększyć wydajność w czasie wykonywania.
Tablice opisane poniżej muszą mieć taki sam rozmiar jak struktura dex method_id_item
powiązana z metodą. W przeciwnym razie w czasie wykonywania zostanie wygenerowany błąd java.lang.reflect.MalformedParametersException
.
Oznacza to, że method_id_item.proto_idx
->
proto_id_item.parameters_off
->
type_list.size
musi być takie samo jak names().length
i
accessFlags().length
.
Funkcja MethodParameters
opisuje wszystkie formalne parametry metody, nawet te, które nie są jawnie ani domyślnie zadeklarowane w kodzie źródłowym. Dlatego rozmiar tablic może się różnić od podpisu lub innych informacji metadanych, które są oparte tylko na jawnych parametrach zadeklarowanych w kodzie źródłowym. MethodParameters
nie będzie też zawierać żadnych informacji o parametrach typu annotation receiver, które nie występują w rzeczywistej sygnaturze metody.
Nazwa | Format | Opis |
---|---|---|
nazwy | Ciąg znaków[] | Nazwy parametrów formalnych powiązanej metody. Tablica nie może być pusta, ale musi być pusta, jeśli nie ma parametrów formalnych. Wartość w tablicy musi być null, jeśli parametr formalny o tym indeksie nie ma nazwy. Jeśli ciągi znaków nazw parametrów są puste lub zawierają „.”, „\”, „[” lub „/”, to w czasie wykonywania zostanie rzucony błąd java.lang.reflect.MalformedParametersException .
|
accessFlags | int[] | Flagi dostępu parametrów formalnych powiązanej metody. Tablica nie może być pusta, ale musi być pusta, jeśli nie ma formalnych parametrów. Ta wartość to maska bitowa o tych wartościach:
java.lang.reflect.MalformedParametersException .
|
dalvik.annotation.Signature
Występuje w klasach, polach i metodach
Do każdej klasy, pola lub metody, która jest zdefiniowana w terminach bardziej złożonego typu niż type_id_item
, jest dołączona adnotacja Signature
. Format .dex
nie definiuje formatu podpisów; ma on jedynie reprezentować podpisy wymagane przez język źródłowy w celu prawidłowego wdrożenia jego semantyki. Dlatego podpisy nie są zwykle analizowane (ani weryfikowane) przez implementacje maszyn wirtualnych. Podpisy są po prostu przekazywane do interfejsów API i narzędzi wyższego poziomu (takich jak debugery). Wszelkie użycie podpisu powinno być napisane w taki sposób, aby nie zakładać, że otrzymano tylko prawidłowe podpisy, i w jasny sposób chronić się przed możliwością otrzymania nieprawidłowego podpisu pod względem składni.
Ponieważ ciągi podpisu zwykle zawierają wiele powtarzających się treści, adnotacja Signature
jest definiowana jako tabelka ciągów tekstowych, w których duplikowane elementy odwołują się do tych samych danych źródłowych, a podpis jest traktowany jako konkatenacja wszystkich ciągów w tabelce. Nie ma żadnych reguł dotyczących tego, jak rozbić podpis na osobne ciągi znaków. To zależy wyłącznie od narzędzi generujących pliki .dex
.
Nazwa | Format | Opis |
---|---|---|
wartość | Ciąg znaków[] | sygnaturę tej klasy lub elementu jako tablicę ciągów, które mają zostać złączone |
dalvik.annotation.Throws
Pojawia się w metodach
Do każdej metody, która deklaruje wyrzucanie co najmniej 1 typu wyjątku, jest dołączona adnotacja Throws
.
Nazwa | Format | Opis |
---|---|---|
wartość | Class[] | tablica typów wyjątków, które zostały zgłoszone |