Format wykonywalny Dalvik

W tym dokumencie opisujemy układ i zawartość plików .dex, które służą do przechowywania zestawu definicji klas i powiązanych z nimi danych dodatkowych.

Przewodnik po typach

Nazwa Opis
bajt 8-bitowa liczba całkowita ze znakiem
ubyte 8-bitowa liczba całkowita bez znaku
krótki 16-bitowa liczba całkowita ze znakiem, little-endian
ushort 16-bitowa liczba całkowita bez znaku, little-endian
int 32-bitowa liczba całkowita ze znakiem, kolejność bajtów little-endian
uint 32-bitowa liczba całkowita bez znaku, little-endian
długi 64-bitowa liczba całkowita ze znakiem, little-endian
ulung 64-bitowa liczba całkowita bez znaku, little-endian
sleb128 liczba całkowita ze znakiem LEB128, o zmiennej długości (patrz poniżej);
uleb128 liczba całkowita bez znaku LEB128 o zmiennej długości (patrz poniżej)
uleb128p1 niepodpisana liczba 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 liczb całkowitych ze znakiem lub bez znaku. Format został zaczerpnięty ze specyfikacji DWARF3. W pliku .dex kodowanie LEB128 jest używane tylko do kodowania 32-bitowych wartości.

Każda wartość zakodowana w formacie LEB128 składa się z 1–5 bajtów, które razem reprezentują pojedynczą 32-bitową wartość. Każdy bajt ma ustawiony najbardziej znaczący bit, z wyjątkiem ostatniego bajtu w sekwencji, który ma wyczyszczony najbardziej znaczący bit. Pozostałe 7 bitów każdego bajtu to ładunek. Najmniej znaczące 7 bitów ilości znajduje się w pierwszym bajcie, kolejne 7 bitów w drugim bajcie itd. W przypadku liczby LEB128 ze znakiem (sleb128) najbardziej znaczący bit ładunku ostatniego bajtu w sekwencji jest rozszerzany ze znakiem, aby uzyskać wartość końcową. W przypadku liczb bez znaku (uleb128) wszystkie bity, które nie są wyraźnie reprezentowane, są interpretowane jako 0.

Diagram bitowy 2-bajtowej wartości LEB128
Pierwszy bajt Drugi bajt
1 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0 bit13 bit12 bit11 bit10 bit9 bit8 bit7

Wariant uleb128p1 służy do przedstawiania wartości ze znakiem, gdzie reprezentacja jest wartością plus jeden zakodowaną jako uleb128. Dzięki temu kodowanie liczby -1 (alternatywnie traktowanej jako wartość bez znaku 0xffffffff) – ale nie żadnej innej liczby ujemnej – zajmuje tylko 1 bajt. Jest to przydatne w tych przypadkach, w których reprezentowana liczba musi być nieujemna lub równa -1 (lub 0xffffffff), a inne wartości ujemne są niedozwolone (lub gdy duże wartości bez znaku są mało prawdopodobne).

Oto kilka przykładów formatów:

Zakodowana sekwencja Jak sleb128 Jak uleb128 Jak uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

Układ pliku

Nazwa Format Opis
nagłówek header_item nagłówek,
string_ids string_id_item[] lista identyfikatorów ciągów znaków. Są to identyfikatory wszystkich ciągów znaków używanych w tym pliku, zarówno do nazewnictwa wewnętrznego (np. deskryptory typów), jak i jako stałe obiekty, do których odwołuje się kod. Lista musi być posortowana według zawartości ciągu znaków z użyciem wartości punktów kodowych UTF-16 (nie w sposób zależny od ustawień regionalnych) i nie może zawierać zduplikowanych wpisów.
type_ids type_id_item[] listę identyfikatorów typów. Są to identyfikatory wszystkich typów (klas, tablic lub typów prostych), do których odwołuje się ten plik, niezależnie od tego, czy są one w nim zdefiniowane. Lista musi być posortowana według indeksu string_id i nie może zawierać zduplikowanych pozycji.
proto_ids proto_id_item[] lista identyfikatorów prototypów metod. Są to identyfikatory wszystkich prototypów, do których odwołuje się ten plik. Lista musi być posortowana według typu zwracanego (według indeksu type_id) w kolejności głównej, a następnie według listy argumentów (porządek leksykograficzny, poszczególne argumenty posortowane według indeksu type_id). Lista nie może zawierać zduplikowanych pozycji.
field_ids field_id_item[] listę identyfikatorów pól. Są to identyfikatory wszystkich pól, do których odwołuje się ten plik, niezależnie od tego, czy są w nim zdefiniowane. Ta lista musi być posortowana, przy czym typ definiujący (według indeksu type_id) jest głównym porządkiem, nazwa pola (według indeksu string_id) jest porządkiem pośrednim, a typ (według indeksu type_id) jest porządkiem pomocniczym. Lista nie może zawierać zduplikowanych pozycji.
method_ids method_id_item[] lista identyfikatorów metod. Są to identyfikatory wszystkich metod, do których odwołuje się ten plik, niezależnie od tego, czy są w nim zdefiniowane. Ta lista musi być posortowana, przy czym typ definiujący (według indeksu type_id) jest głównym porządkiem, nazwa metody (według indeksu string_id) jest porządkiem pośrednim, a prototyp metody (według indeksu proto_id) jest porządkiem podrzędnym. Lista nie może zawierać zduplikowanych pozycji.
class_defs class_def_item[] listę definicji klas. Klasy muszą być uporządkowane w taki sposób, aby klasa nadrzędna i zastosowane interfejsy danej klasy pojawiały się na liście wcześniej niż klasa odwołująca się. Ponadto nieprawidłowe jest, aby definicja klasy o tej samej nazwie pojawiała się na liście więcej niż raz.
call_site_ids call_site_id_item[] lista identyfikatorów witryn połączeń. Są to identyfikatory wszystkich witryn połączeń, do których odwołuje się ten plik, niezależnie od tego, czy są one w nim zdefiniowane. Ta lista musi być posortowana w kolejności rosnącej według kolumny call_site_off.
method_handles method_handle_item[] lista uchwytów metod. Lista wszystkich uchwytów metod, do których odwołuje się ten plik, niezależnie od tego, czy są one w nim zdefiniowane. Lista nie jest posortowana i może zawierać duplikaty, które logicznie odpowiadają różnym instancjom uchwytów metod.
dane ubyte[] obszar danych zawierający wszystkie dane pomocnicze do tabel wymienionych powyżej; Różne elementy mają różne wymagania dotyczące wyrównania, a w razie potrzeby przed każdym elementem wstawiane są bajty dopełniające, aby uzyskać 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. W niepołączonych plikach ta sekcja jest pusta, a implementacje środowiska wykonawczego mogą jej używać w dowolny sposób.

Format kontenera

Wersja 41 wprowadza nowy format kontenera danych DEX, który ma na celu oszczędzanie miejsca. Ten format kontenera umożliwia łączenie kilku logicznych plików DEX w jeden plik fizyczny. Nowy format to w większości proste połączenie plików w poprzednim formacie, ale występują pewne różnice:

  • file_size to rozmiar pliku logicznego, a nie fizycznego. Można go używać do iteracji po wszystkich plikach logicznych w kontenerze.
  • Logiczne pliki DEX mogą odwoływać się do dowolnych późniejszych danych w kontenerze (ale nie do wcześniejszych). Dzięki temu pliki DEX mogą udostępniać sobie dane, np. ciągi znaków.
  • Wszystkie przesunięcia są względne w stosunku do pliku fizycznego. Brak przesunięcia względem nagłówka. Dzięki temu sekcje z przesunięciami można udostępniać 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.
  • Atrybuty data_size i data_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ła tablica/ciąg znaków DEX_FILE_MAGIC to lista bajtów, które muszą znajdować się na początku pliku .dex, aby został on rozpoznany jako taki. Wartość celowo zawiera znak nowego wiersza ("\n" lub 0x0a) i znak null ("\0" lub 0x00), aby ułatwić wykrywanie niektórych form uszkodzenia. Wartość ta zawiera też numer wersji formatu w postaci 3-cyfrowej liczby dziesiętnej, która powinna rosnąć monotonicznie wraz z ewolucją formatu.

ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 }
                        = "dex\n039\0"

Uwaga: obsługa wersji 041 formatu została dodana w Androidzie 16, który obsługuje format kontenera.

Uwaga: obsługa wersji 040 formatu została dodana w Androidzie 10.0, co rozszerzyło zestaw dozwolonych znaków w SimpleNames.

Uwaga: obsługa wersji 039 formatu została dodana w Androidzie 9.0, w którym wprowadzono 2 nowe kody bajtowe: const-method-handleconst-method-type. (Każdy z nich jest opisany w tabeli Podsumowanie zestawu kodu bajtowego). W Androidzie 10 wersja 039 rozszerza format pliku DEX o ukryte informacje o interfejsie API, które mają zastosowanie tylko do plików DEX na ścieżce klasy rozruchowej.

Uwaga: obsługa wersji 038 formatu została dodana w Androidzie 8.0. Wersja 038 dodała nowe kody bajtowe (invoke-polymorphicinvoke-custom) oraz dane do obsługi metod.

Uwaga: obsługa wersji 037 formatu została dodana w Androidzie 7.0. Przed wersją 037 większość wersji Androida korzystała z wersji 035 tego formatu. Jedyna różnica między wersjami 035037 polega na dodaniu metod domyślnych i dostosowaniu invoke.

Uwaga: co najmniej kilka wcześniejszych wersji formatu było używanych w ogólnodostępnych wersjach oprogramowania. 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 platformy Android (luty–marzec 2008 r.). W wielu aspektach te wcześniejsze wersje formatu znacznie różnią się od wersji opisanej w tym dokumencie.

ENDIAN_CONSTANT i REVERSE_ENDIAN_CONSTANT

Umieszczony w header_item

Stała ENDIAN_CONSTANT służy do określania kolejności bajtów w pliku, w którym się znajduje. Chociaż standardowy format .dex jest zapisywany w formacie little-endian, implementacje mogą zamieniać bajty. Jeśli implementacja napotka nagłówek, którego endian_tag ma wartość REVERSE_ENDIAN_CONSTANT zamiast ENDIAN_CONSTANT, będzie wiedzieć, że plik został zamieniony bajtami z oczekiwanej formy.

uint ENDIAN_CONSTANT = 0x12345678;
uint REVERSE_ENDIAN_CONSTANT = 0x78563412;

NO_INDEX

Umieszczony w elementach class_def_item i debug_info_item

Stała NO_INDEX służy do wskazania, ż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 flag dostępu

Umieszczony w elementach class_def_item, encoded_field, encoded_method i InnerClass

Pola bitowe tych flag służą do wskazywania dostępności i ogólnych właściwości klas oraz elementów klas.

Nazwa Wartość W przypadku zajęć (i adnotacji InnerClass) For Fields 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 skonstruowany z odwołaniem do zewnętrznego this static: globalny dla klasy definiującej static: nie przyjmuje argumentu this
ACC_FINAL 0x10 final: nie można utworzyć podklasy final: niezmienny po utworzeniu final: nie można zastąpić
ACC_SYNCHRONIZED 0x20     synchronized: powiązany zamek jest automatycznie uzyskiwany w trakcie wywołania tej metody.

Uwaga: to ustawienie jest prawidłowe tylko wtedy, gdy ustawiona jest też wartość parametru ACC_NATIVE.

ACC_VOLATILE 0x40   volatile: specjalne reguły dostępu, które pomagają w zapewnieniu bezpieczeństwa wątków;  
ACC_BRIDGE 0x40     metoda pomostowa, dodawana automatycznie przez kompilator jako bezpieczny typowo pomost
ACC_TRANSIENT 0x80   transient: nie zapisywać w przypadku domyślnej serializacji  
ACC_VARARGS 0x80     ostatni argument powinien być traktowany przez kompilator jako argument „rest”
ACC_NATIVE 0x100     native: zaimplementowane w kodzie natywnym
ACC_INTERFACE 0x200 interface: klasa abstrakcyjna z możliwością wielokrotnej implementacji    
ACC_ABSTRACT 0x400 abstract: nie można bezpośrednio utworzyć instancji   abstract: nie zaimplementowano w tej klasie
ACC_STRICT 0x800     strictfp: ścisłe reguły arytmetyki zmiennoprzecinkowej
ACC_SYNTHETIC 0x1000 nie jest zdefiniowany bezpośrednio w kodzie źródłowym, nie jest zdefiniowany bezpośrednio w kodzie źródłowym, nie jest zdefiniowany bezpośrednio w kodzie źródłowym,
ACC_ANNOTATION 0x2000 zadeklarowany jako klasa adnotacji,    
ACC_ENUM 0x4000 zadeklarowany jako typ wyliczeniowy, zadeklarowany jako wartość wyliczeniowa.  
(nieużywane) 0x8000      
ACC_CONSTRUCTOR 0x10000     metoda konstruktora (inicjator klasy lub instancji);
ACC_DECLARED_
SYNCHRONIZED
0x20000     zadeklarowano synchronized.

Uwaga: nie ma to wpływu na wykonanie (poza odzwierciedleniem tej flagi).

* Dozwolone tylko w przypadku adnotacji InnerClass. Nie może być nigdy w przypadku class_def_item.

Zmodyfikowane kodowanie UTF-8

Aby ułatwić obsługę starszych wersji, format .dex koduje dane tekstowe w zmodyfikowanej formie UTF-8, która jest standardem de facto i którą będziemy dalej nazywać MUTF-8. Ten format jest identyczny ze standardowym formatem UTF-8, z wyjątkiem:

  • Używane są tylko kodowania 1-, 2- i 3-bajtowe.
  • Punkty kodowe z zakresu U+10000 … U+10ffff są kodowane jako para zastępcza, z których każdy jest reprezentowany jako 3-bajtowa zakodowana wartość.
  • Punkt kodowy U+0000 jest zakodowany w formacie dwubajtowym.
  • Zwykły bajt zerowy (wartość 0) oznacza koniec ciągu, zgodnie ze standardową interpretacją w języku C.

Pierwsze 2 punkty można podsumować w ten sposób: MUTF-8 to format kodowania UTF-16, a nie bardziej bezpośredni format kodowania znaków Unicode.

Dwa ostatnie elementy powyżej umożliwiają jednocześnie umieszczenie punktu kodowego U+0000 w ciągu znaków i manipulowanie nim jako ciągiem znaków zakończonym znakiem null w stylu C.

Specjalne kodowanie znaku U+0000 oznacza jednak, że w przeciwieństwie do zwykłego kodowania UTF-8 wynik wywołania standardowej funkcji języka C strcmp() na parze ciągów MUTF-8 nie zawsze wskazuje prawidłowo podpisany wynik porównania nierównych ciągów. Jeśli ważna jest kolejność (nie tylko równość), najprostszym sposobem porównania ciągów znaków MUTF-8 jest dekodowanie ich znak po znaku i porównywanie zdekodowanych wartości. (Możliwe są jednak bardziej zaawansowane implementacje).

Więcej informacji o kodowaniu znaków znajdziesz w standardzie Unicode. MUTF-8 jest w rzeczywistości bliższy (stosunkowo mniej znanemu) kodowaniu CESU-8 niż UTF-8.

kodowanie encoded_value

Umieszczony w elementach annotation_element i encoded_array_item

encoded_value to zakodowany fragment (prawie) dowolnych danych o strukturze hierarchicznej. Kodowanie ma być zarówno kompaktowe, jak i łatwe do analizowania.

Nazwa Format Opis
(value_arg << 5) | value_type ubyte bajt wskazujący typ bezpośrednio następującego value wraz z opcjonalnym argumentem wyjaśniającym w 3 bitach wyższego rzędu. Poniżej znajdziesz różne value definicje. W większości przypadków value_arg koduje długość bezpośrednio następującego po nim pola value w bajtach, np.(size - 1). 0 oznacza, że wartość wymaga 1 bajta, a 7 – 8 bajtów. Istnieją jednak wyjątki, o których piszemy poniżej.
wartość ubyte[] bajtów reprezentujących wartość o zmiennej długości, które są interpretowane w różny sposób w zależności od bajtów value_type, ale zawsze w formacie little-endian. Szczegółowe informacje znajdziesz w definicjach różnych wartości poniżej.

Formaty wartości

Wpisz nazwę value_type value_arg Format value Format Opis
VALUE_BYTE 0x00 (brak; musi być 0) ubyte[1] 1-bajtowa liczba całkowita ze znakiem
VALUE_SHORT 0x02 size - 1 (0…1) ubyte[size] dwubajtowa liczba całkowita ze znakiem, rozszerzona o znak;
VALUE_CHAR 0x03 size - 1 (0…1) ubyte[size] wartość całkowita bez znaku o długości 2 bajtów, uzupełniona zerami;
VALUE_INT 0x04 size - 1 (0…3) ubyte[size] wartość całkowita ze znakiem o długości 4 bajtów, rozszerzona o znak;
VALUE_LONG 0x06 rozmiar – 1 (0–7) ubyte[size] ośmiobajtowa liczba całkowita ze znakiem, rozszerzona o znak;
VALUE_FLOAT 0x10 size - 1 (0…3) ubyte[size] 4-bajtowy wzorzec bitowy, rozszerzony zerami po prawej stronie i interpretowany jako 32-bitowa wartość zmiennoprzecinkowa IEEE754.
VALUE_DOUBLE 0x11 rozmiar – 1 (0–7) ubyte[size] 8-bajtowy wzorzec bitowy, uzupełniony zerami z prawej strony i interpretowany jako 64-bitowa wartość zmiennoprzecinkowa IEEE754.
VALUE_METHOD_TYPE 0x15 size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa wartość całkowita, interpretowana jako indeks w sekcji proto_ids i reprezentująca wartość typu metody.
VALUE_METHOD_HANDLE 0x16 size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa wartość całkowita, interpretowana jako indeks w sekcji method_handles i reprezentująca wartość uchwytu metody;
VALUE_STRING 0x17 size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa wartość całkowita, interpretowana jako indeks w sekcji string_ids i reprezentująca wartość ciągu znaków.
VALUE_TYPE 0x18 size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa wartość całkowita, która jest interpretowana jako indeks w sekcji type_ids i reprezentuje wartość typu/klasy odbijającej;
VALUE_FIELD 0x19 size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa liczba całkowita, interpretowana jako indeks w sekcji field_ids i reprezentująca wartość pola odblaskowego.
VALUE_METHOD 0x1a size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa liczba całkowita, interpretowana jako indeks w sekcji method_ids i reprezentująca wartość metody refleksyjnej.
VALUE_ENUM 0x1b size - 1 (0…3) ubyte[size] niepodpisana (rozszerzona do zera) 4-bajtowa liczba całkowita, interpretowana jako indeks w sekcji field_ids i reprezentująca wartość stałej typu wyliczeniowego.
VALUE_ARRAY 0x1c (brak; musi być 0) encoded_array tablicę wartości w formacie określonym poniżej w sekcji „encoded_array format”. Rozmiar value jest określony w kodowaniu.
VALUE_ANNOTATION 0x1d (brak; musi być 0) encoded_annotation podrzędną adnotację w formacie określonym poniżej w sekcji „encoded_annotation format”. Rozmiar value jest określony w kodowaniu.
VALUE_NULL 0x1e (brak; musi być 0) (brak) null wartość referencyjna
VALUE_BOOLEAN 0x1f wartość logiczna (0–1) (brak) wartość 1-bitowa: 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] ciąg sekwencji bajtów size encoded_value 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 (nie tablicy ani typu prostego).
rozmiar uleb128 liczba mapowań nazwa-wartość w tej adnotacji.
elementów annotation_element[size] elementy adnotacji, które są reprezentowane bezpośrednio w tekście (nie jako przesunięcia). Elementy muszą być posortowane w kolejności rosnącej według string_idindeksu.

format annotation_element

Nazwa Format Opis
name_idx uleb128 nazwa elementu, reprezentowana jako indeks w sekcji string_ids. Ciąg znaków musi być zgodny ze składnią MemberName zdefiniowaną powyżej.
wartość encoded_value wartość elementu,

Składnia ciągu tekstowego

W pliku .dex jest kilka rodzajów elementów, które ostatecznie odnoszą się do ciągu znaków. Poniższe definicje w stylu BNF określają dopuszczalną składnię tych ciągów tekstowych.

SimpleName

SimpleName to podstawa składni nazw innych elementów. Format .dex daje w tym przypadku sporą swobodę (znacznie większą niż większość popularnych języków źródłowych). Krótko mówiąc, prosta nazwa składa się z dowolnego znaku alfabetu lub cyfry z zakresu ASCII, kilku konkretnych symboli z zakresu ASCII oraz większości punktów kodowych spoza zakresu ASCII, które nie są znakami sterującymi, spacjami ani znakami specjalnymi. Od wersji 040 format dopuszcza też spacje (kategoria Unicode Zs ). Pamiętaj, że punkty kodowe zastępcze (w zakresie U+d800U+dfff) nie są same w sobie uznawane za prawidłowe znaki w nazwie, ale dodatkowe znaki Unicode prawidłowe (są one reprezentowane przez ostatnią alternatywę reguły SimpleNameChar) i powinny być reprezentowane w pliku jako pary zastępczych punktów kodowych w kodowaniu 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

MemberName to nazwa elementu klasy, przy czym elementami są pola, metody i klasy wewnętrzne.

MemberName
SimpleName
| '<' SimpleName '>'

FullClassName

FullClassName to pełna nazwa klasy, która zawiera opcjonalny specyfikator pakietu, a po nim wymaganą nazwę.

FullClassName
OptionalPackagePrefix SimpleName
OptionalPackagePrefix
(SimpleName '/')*

TypeDescriptor

Używane przez type_id_item

TypeDescriptor to reprezentacja dowolnego typu, w tym typów prostych, klas, tablic i void. Poniżej znajdziesz wyjaśnienie znaczenia poszczególnych wersji.

TypeDescriptor
'V'
| FieldTypeDescriptor
FieldTypeDescriptor
NonArrayFieldTypeDescriptor
| ('[' * 1…255) NonArrayFieldTypeDescriptor
NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' FullClassName ';'

ShortyDescriptor

Używane przez proto_id_item

ShortyDescriptor to skrócona reprezentacja prototypu metody, w tym typów zwracanych i parametrów, z wyjątkiem tego, że nie ma rozróżnienia między różnymi typami odwołań (klasa lub tablica). 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 TypeDescriptor

Oto znaczenie poszczególnych wariantów elementu 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
Lfully/qualified/Name; zajęcia fully.qualified.Name
[descriptor tablica descriptor, której można używać rekursywnie 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ą pojawić się 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 wartość magiczną. Więcej informacji znajdziesz w sekcji „DEX_FILE_MAGIC” powyżej.
suma kontrolna uint Suma kontrolna adler32 pozostałej części pliku (wszystko oprócz magic i tego pola); służy do wykrywania uszkodzenia pliku.
podpis ubyte[20] Podpis SHA-1 (skrót) pozostałej części pliku (wszystko oprócz magic, checksum i tego pola); służy do jednoznacznej identyfikacji plików.
file_size uint

rozmiar całego pliku (wraz z nagłówkiem) w bajtach(wersja 40 lub starsza)

odległość w bajtach od początku tego nagłówka do następnego nagłówka lub do końca całego pliku (kontenera). (wersja 41 lub nowsza)

header_size uint

rozmiar nagłówka (całej tej sekcji) w bajtach. Zapewnia to przynajmniej ograniczoną zgodność wsteczną i w przód bez unieważniania formatu.

musi mieć 112 bajtów (0x70)(wersja 40 lub starsza)

musi mieć 120 bajtów (0x78) (wersja 41 lub nowsza)

endian_tag uint = ENDIAN_CONSTANT tag kolejności bajtów. Więcej informacji znajdziesz w omówieniu powyżej w sekcji „ENDIAN_CONSTANTREVERSE_ENDIAN_CONSTANT”.
link_size uint rozmiar sekcji linków lub 0, jeśli ten plik nie jest statycznie połączony.
link_off uint przesunięcie od początku pliku do sekcji linku lub0 jeśli link_size == 0. Jeśli przesunięcie jest różne od zera, powinno wskazywać przesunięcie w sekcji link_data. Format danych, na które wskazuje ten nagłówek, nie jest określony w tym dokumencie. Ten nagłówek (i poprzedni) pozostawiono jako punkty zaczepienia do wykorzystania przez implementacje środowiska wykonawczego.
map_off uint przesunięcie od początku pliku do elementu mapy. Przesunięcie, które musi być niezerowe, powinno być przesunięciem do sekcji data, a dane powinny być w formacie określonym poniżej w sekcji „map_list”.
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ągów znaków lub0, jeśli string_ids_size == 0 (przyznaję, że to dziwny przypadek skrajny). Przesunięcie, jeśli jest różne od zera, powinno być względem początku sekcji string_ids.
type_ids_size uint liczba elementów na liście identyfikatorów typów, 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 (przyznaję, że to dziwny przypadek brzegowy). Przesunięcie, jeśli jest różne od zera, powinno być względem początku sekcji type_ids.
proto_ids_size uint liczba elementów na liście identyfikatorów prototypów, maksymalnie 65535
proto_ids_off uint przesunięcie od początku pliku do listy identyfikatorów prototypów lub 0, jeśli proto_ids_size == 0 (przyznaję, że to dziwny przypadek skrajny). Przesunięcie, jeśli jest różne od zera, powinno być względem 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. Przesunięcie, jeśli jest niezerowe, powinno być względem początku sekcji field_ids.
method_ids_size uint liczba elementów na liście identyfikatorów metod.
method_ids_off uint przesunięcie od początku pliku do listy identyfikatorów metod lub 0, jeśli method_ids_size == 0. Przesunięcie, jeśli jest niezerowe, powinno być względem 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 (przyznaję, że to dziwny przypadek brzegowy). Przesunięcie, jeśli jest różne od zera, powinno być względem początku sekcji class_defs.
data_size uint

Rozmiar sekcji data w bajtach. Musi to być parzysta wielokrotność rozmiaru sizeof(uint). (wersja 40 lub starsza)

Nieużywane (wersja 41 lub nowsza)

data_off uint

przesunięcie od początku pliku do początku sekcji data(wersja 40 lub starsza)

Nieużywane (wersja 41 lub nowsza)

container_size uint

to pole nie istnieje. Można założyć, że jest równa file_size. (wersja 40 lub starsza)

rozmiar całego pliku (wraz z innymi nagłówkami dex i ich danymi); (wersja 41 lub nowsza)

header_offset uint

to pole nie istnieje. Można założyć, że jest równa 0. (wersja 40 lub starsza)

przesunięcie od początku pliku do początku tego nagłówka. (wersja 41 lub nowsza)

map_list

Występuje w sekcji danych

Odniesienie z header_item

Wyrównanie: 4 bajty

Jest to lista całej zawartości pliku w odpowiedniej kolejności. Zawiera pewne powtórzenia w stosunku do header_item, ale ma być łatwym w użyciu formularzem do iteracji po całym pliku. Dany typ może wystąpić w mapie co najwyżej raz, ale nie ma ograniczeń co do kolejności, w jakiej mogą się pojawiać typy, z wyjątkiem ograniczeń wynikających z pozostałej części formatu (np. sekcja header musi pojawić się jako pierwsza, a po niej sekcja string_ids itp.). Dodatkowo wpisy na mapie muszą być uporządkowane według początkowego przesunięcia i nie mogą się nakładać.

Nazwa Format Opis
rozmiar uint rozmiar listy (w postaci liczby wpisów),
lista map_item[size] elementy listy,

map_item format

Nazwa Format Opis
typ ushort rodzaj produktów (patrz tabela poniżej);
unused ushort (nieużywane)
rozmiar uint liczba elementów, które mają się znajdować w wskazanym przesunięciu.
przesunięcie, uint przesunięcie od początku pliku do elementów, których dotyczy problem;

Kody typów

Typ produktu 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 domyślny; musi być przeanalizowany
code_item TYPE_CODE_ITEM 0x2001 domyślny; musi być przeanalizowany
string_data_item TYPE_STRING_DATA_ITEM 0x2002 domyślny; musi być przeanalizowany
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 domyślny; musi być przeanalizowany
annotation_item TYPE_ANNOTATION_ITEM 0x2004 domyślny; musi być przeanalizowany
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 domyślny; musi być przeanalizowany
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 domyślny; musi być przeanalizowany
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 domyślny; musi być przeanalizowany

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 dla tego elementu. Przesunięcie powinno odnosić się do lokalizacji w sekcji data, a dane powinny mieć format określony poniżej w sekcji „string_data_item”. Przesunięcie nie musi być wyrównane.

string_data_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

Nazwa Format Opis
utf16_size uleb128 rozmiar tego ciągu znaków w jednostkach kodu UTF-16 (w wielu systemach jest to „długość ciągu znaków”). Jest to zdekodowana długość ciągu. (Zakodowana długość jest określana przez pozycję bajtu 0).
dane ubyte[] ciąg jednostek kodu MUTF-8 (czyli oktetów lub bajtów) zakończony bajtem o wartości 0. Szczegółowe informacje i omówienie formatu danych znajdziesz w sekcji „Kodowanie MUTF-8 (zmodyfikowane UTF-8)” powyżej.

Uwaga: dopuszczalne jest użycie ciągu znaków, który zawiera (zakodowane) jednostki kodu zastępczego UTF-16 (czyli U+d800 … U+dfff) w izolacji lub w nieprawidłowej kolejności w stosunku do zwykłego kodowania Unicode w UTF-16. Od wyższych poziomów użycia ciągów znaków zależy odrzucanie takich nieprawidłowych kodowań, jeśli jest to odpowiednie.

type_id_item

Występuje w sekcji type_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
descriptor_idx uint indeks w string_ids liście ciągu znaków deskryptora tego typu. Ciąg znaków musi być zgodny ze składnią TypeDescriptor zdefiniowaną powyżej.

proto_id_item

Wyświetla się w sekcji proto_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
shorty_idx uint indeks w string_ids dla krótkiego ciągu znaków opisującego ten prototyp. Ciąg znaków musi być zgodny ze składnią ShortyDescriptor zdefiniowaną powyżej i odpowiadać typowi zwracanych danych oraz parametrom tego elementu.
return_type_idx uint indeks w type_ids dla typu zwracanego tego prototypu
parameters_off uint przesunięcie od początku pliku do listy typów parametrów dla tego prototypu lub 0, jeśli ten prototyp nie ma parametrów. Jeśli ten przesunięcie jest różne od zera, powinno znajdować się w sekcji data, a dane w niej powinny mieć format określony przez "type_list" poniżej. Poza tym na liście nie powinno być odwołania do typu void.

field_id_item

Pojawia się w sekcji field_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
class_idx ushort indeks na liście type_ids dla definicji tego pola. Musi to być typ klasy, a nie tablica ani typ prosty.
type_idx ushort indeks na liście type_ids dla typu tego pola.
name_idx uint indeks do listy string_ids dla nazwy tego pola. Ciąg znaków musi być zgodny ze składnią MemberName zdefiniowaną powyżej.

method_id_item

Wyświetla się 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 prosty.
proto_idx ushort indeks na liście proto_ids dla prototypu tej metody
name_idx uint indeks w string_ids liście nazwy tej metody. Ciąg znaków musi być zgodny ze składnią MemberName zdefiniowaną 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 tych zajęć. Musi to być typ klasy, a nie tablica ani typ prosty.
access_flags uint flagi dostępu do klasy (public, final itp.); Więcej informacji znajdziesz w sekcji „access_flagsDefinicje”.
superclass_idx uint indeks na liście type_ids dla klasy nadrzędnej lub stała NO_INDEX, jeśli ta klasa nie ma klasy nadrzędnej (czyli jest klasą główną, np. Object). Jeśli ten element jest obecny, musi to być typ klasy, a nie tablica ani typ prosty.
interfaces_off uint przesunięcie od początku pliku do listy interfejsów lub 0, jeśli nie ma żadnych interfejsów. Ten przesunięcie powinno znajdować się w sekcji data, a dane w niej powinny mieć format określony poniżej w sekcji „type_list”. Każdy element listy musi być typem klasy (nie może być tablicą ani typem prostym) i nie może zawierać duplikatów.
source_file_idx uint indeks na liście string_ids dla nazwy pliku zawierającego oryginalne źródło (przynajmniej większości) tej klasy lub wartość specjalną NO_INDEX, która oznacza brak tych informacji. debug_info_item dowolnej metody może zastąpić ten plik źródłowy, ale oczekuje 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 tej klasy lub 0, jeśli w tej klasie nie ma adnotacji. Jeśli ten przesunięcie jest różne od zera, powinno znajdować się w sekcji data, a dane w tej sekcji powinny mieć format określony poniżej przez „annotations_directory_item”, przy czym wszystkie elementy odwołujące się do tej klasy powinny być definiowane przez nią.
class_data_off uint przesunięcie od początku pliku do powiązanych danych zajęć dla tego elementu lub 0, jeśli nie ma danych zajęć dla tych zajęć. (Może to mieć miejsce np. w przypadku, gdy ta klasa jest interfejsem znacznika). Jeśli przesunięcie jest różne od zera, powinno znajdować się w sekcji data, a dane w tej sekcji powinny mieć format określony przez „class_data_item” poniżej. Wszystkie elementy powinny odwoływać się do tej klasy jako definicji.
static_values_off uint przesunięcie od początku pliku do listy wartości początkowych pól static lub 0, jeśli nie ma żadnych pól (a wszystkie pola static mają być inicjowane wartością 0 lub null). To przesunięcie powinno znajdować się w sekcji data, a dane w niej powinny mieć format określony poniżej w sekcji „encoded_array_item”. 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 field_list. Typ każdego elementu tablicy musi być zgodny z zadeklarowanym typem odpowiedniego pola. Jeśli w tablicy jest mniej elementów niż pól static, pozostałe pola są inicjowane odpowiednim typem 0 lub null.

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 miejsca wywołania. Przesunięcie powinno znajdować się w sekcji danych, a dane w niej powinny mieć format określony w sekcji „call_site_item” poniżej.

call_site_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

call_site_item to encoded_array_item, którego elementy odpowiadają argumentom przekazanym do metody linkera bootstrap. Pierwsze 3 argumenty to:

  1. Uchwyt metody reprezentujący metodę linkera bootstrap (VALUE_METHOD_HANDLE).
  2. Nazwa metody, którą powinien rozwiązać linker bootstrap (VALUE_STRING).
  3. Typ metody odpowiadający typowi nazwy metody do rozwiązania (VALUE_METHOD_TYPE).

Wszystkie dodatkowe argumenty to stałe wartości przekazywane do metody linkera bootstrap. Argumenty te są przekazywane w kolejności i bez konwersji typów.

Uchwyt metody reprezentujący metodę linkera bootstrap musi mieć typ zwracany java.lang.invoke.CallSite. Pierwsze 3 typy parametrów to:

  1. java.lang.invoke.Lookup
  2. java.lang.String
  3. java.lang.invoke.MethodType

Typy parametrów dodatkowych argumentów są określane na podstawie ich stałych wartości.

method_handle_item

Pojawia się 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żywane)
field_or_method_id ushort Identyfikator pola lub metody w zależności od tego, czy typ uchwytu metody jest akcesorem czy wywołującym metodę.
unused ushort (nieużywane)

Kody typów uchwytów metod

Stała Wartość Opis
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 Uchwyt metody jest ustawiającym pole statyczne (akcesorem)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 Uchwyt metody jest statycznym pobieraniem pola (akcesorem)
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 Uchwyt metody jest ustawiającym pole instancji (akcesorem)
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 Uchwyt metody jest getterem pola instancji (akcesorem)
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 Uchwyt metody to wywołujący metodę statyczną
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 Uchwyt metody to wywołujący metodę instancji
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 Uchwyt metody to wywołujący metodę konstruktora.
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 Uchwyt metody to bezpośredni wywołujący metodę
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 Uchwyt metody jest wywołaniem metody interfejsu

class_data_item

Odniesienie do elementu class_def_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

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 (dowolne z static, private lub konstruktor), 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 (żadna z metod static, private ani konstruktor), reprezentowane jako sekwencja zakodowanych elementów. Ta lista nie powinna zawierać metod dziedziczonych, chyba że zostały one zastąpione przez klasę, którą reprezentuje ten element. Metody muszą być posortowane według kolumny method_idx w kolejności rosnącej. method_idx metody wirtualnej musi nie być taka sama jak w przypadku żadnej metody bezpośredniej.

Uwaga: wszystkie instancje 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 w field_ids liście tożsamości tego pola (zawiera nazwę i opis), reprezentowany jako różnica w stosunku do 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 itp.). Więcej informacji znajdziesz w sekcji „access_flagsDefinicje”.

Format encoded_method

Nazwa Format Opis
method_idx_diff uleb128 indeks w method_ids liście tożsamości tej metody (zawiera nazwę i opis), reprezentowany jako różnica od indeksu poprzedniego elementu na liście. Indeks pierwszego elementu na liście jest reprezentowany bezpośrednio.
access_flags uleb128 flagi dostępu do metody (public, final itp.). Więcej informacji znajdziesz w sekcji „access_flagsDefinicje”.
code_off uleb128 przesunięcie od początku pliku do struktury kodu tej metody lub 0, jeśli ta metoda ma wartość abstract lub native. Przesunięcie powinno odnosić się do lokalizacji w sekcji data. Format danych jest określony przez „code_item” poniżej.

type_list

Przywoływana przez class_def_item i proto_id_item

Występuje w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
rozmiar uint rozmiar listy (w postaci liczby wpisów),
lista type_item[size] elementy listy,

type_item format

Nazwa Format Opis
type_idx ushort indeks na liście type_ids

code_item

Przywoływana z pola 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 wychodzącej przestrzeni argumentów wymaganej przez ten kod do wywołania metody.
tries_size ushort liczba try_item w tej instancji. Jeśli wartość jest różna od zera, pojawiają się one jako tablica tries tuż po insns w tym przypadku.
debug_info_off uint przesunięcie od początku pliku do sekwencji informacji debugowania (numery wierszy + informacje o zmiennych lokalnych) dla tego kodu lub 0, jeśli nie ma żadnych informacji. Jeśli przesunięcie jest różne od zera, powinno odnosić się do lokalizacji w sekcji data. Format danych jest określony przez „debug_info_item” poniżej.
insns_size uint rozmiar listy instrukcji w 16-bitowych jednostkach kodu,
insns ushort[insns_size] rzeczywistą tablicę kodu bajtowego. Format kodu w insnstablicy jest określony w dokumencie towarzyszącym Dalvik bytecode. Pamiętaj, że choć jest to zdefiniowane jako tablica ushort, niektóre struktury wewnętrzne preferują wyrównanie do 4 bajtów. Jeśli plik jest zapisany w formacie z odwróconą kolejnością bajtów, odwrócenie kolejności bajtów jest wykonywane tylko w przypadku poszczególnych ushort wystąpień, a nie w przypadku większych struktur wewnętrznych.
padding ushort (optional) = 0 2 bajty dopełnienia, aby wyrównać tries do 4 bajtów. Ten element jest obecny tylko wtedy, gdy tries_size jest liczbą różną od zera, a insns_size jest liczbą nieparzystą.
próbuje try_item[tries_size] (opcjonalny) tablica wskazująca, gdzie w kodzie są przechwytywane wyjątki i jak je obsługiwać. Elementy tablicy nie mogą się pokrywać w zakresie i muszą być uporządkowane od najniższego do najwyższego adresu. Ten element występuje tylko wtedy, gdy wartość tries_size jest różna od zera.
moduły obsługi encoded_catch_handler_list (opcjonalnie) bajtów reprezentujących listę list typów przechwytywania i powiązanych adresów procedur obsługi. Każdy try_item ma przesunięcie w bajtach w tej strukturze. Ten element jest obecny tylko wtedy, gdy wartość tries_size jest różna od zera.

Format try_item

Nazwa Format Opis
start_addr uint adres początkowy bloku kodu objętego tym wpisem. Adres to liczba 16-bitowych jednostek kodu do początku pierwszej objętej instrukcji.
insn_count ushort liczba 16-bitowych jednostek kodu objętych tym wpisem. Ostatnia jednostka kodu (włącznie) to start_addr + insn_count - 1.
handler_off ushort przesunięcie w bajtach od początku powiązanego encoded_catch_hander_list do encoded_catch_handler w przypadku tego wpisu. Musi to być przesunięcie względem początku encoded_catch_handler.

encoded_catch_handler_list

Nazwa Format Opis
rozmiar uleb128 rozmiar tej listy (w liczbie wpisów);
lista encoded_catch_handler[handlers_size] rzeczywista lista list obsługi, reprezentowana bezpośrednio (nie jako przesunięcia) i połączona sekwencyjnie.

Format encoded_catch_handler

Nazwa Format Opis
rozmiar sleb128 liczba typów połowów na tej liście. Jeśli jest to liczba nie dodatnia, jest to liczba przeciwna do liczby typów klauzul catch, a po klauzulach catch następuje ogólna obsługa błędów. Na przykład size o wartości 0 oznacza, że istnieje reguła ogólna, ale nie ma reguł z określonym typem. Wartość size w przypadku 2 oznacza, że istnieją 2 jawnie określone reguły przechwytywania i nie ma reguły ogólnej. A size -1 oznacza, że jest jeden typowany warunek wraz z warunkiem ogólnym.
moduły obsługi encoded_type_addr_pair[abs(size)] strumień zakodowanych elementów abs(size), po jednym dla każdego przechwyconego typu, w kolejności, w jakiej typy powinny być testowane.
catch_all_addr uleb128 (opcjonalnie) adres kodu bajtowego obsługi catch-all. Ten element występuje tylko wtedy, gdy wartość size jest nie większa niż 0.

Format encoded_type_addr_pair

Nazwa Format Opis
type_idx uleb128 indeks na type_ids liście typu wyjątku do przechwycenia.
addr uleb128 adres kodu bajtowego powiązanego modułu obsługi wyjątków,

debug_info_item

Odniesienie z code_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

Każdy element debug_info_item definiuje automat stanowy zakodowany w postaci bajtów, inspirowany formatem DWARF3. Po zinterpretowaniu generuje on tabelę pozycji i (potencjalnie) informacje o zmiennych lokalnych dla elementu code_item. Sekwencja zaczyna się od nagłówka o zmiennej długości (która zależy od liczby parametrów metody), po którym następują kody bajtowe automatu stanowego, a kończy się bajtem DBG_END_SEQUENCE.

Automat 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 0 na początku każdej sekwencji debug_info i musi tylko rosnąć monotonicznie. Rejestr line reprezentuje numer wiersza źródłowego, który powinien być powiązany z następnym wpisem w tabeli pozycji wygenerowanym przez automat stanowy. Jest ona inicjowana w nagłówku sekwencji i może zmieniać się w kierunku dodatnim lub ujemnym, ale nigdy nie może być mniejsza niż 1. Rejestr source_file reprezentuje plik źródłowy, do którego odnoszą się wpisy numerów wierszy. Jest on inicjowany wartością source_file_idxclass_def_item. Pozostałe 2 zmienne, prologue_endepilogue_begin, to flagi wartości logicznej (inicjowane jako false), które wskazują, czy następna emitowana pozycja powinna być traktowana jako prolog lub epilog metody. Automat stanowy musi też śledzić nazwę i typ ostatniej zmiennej lokalnej, która jest aktywna w każdym rejestrze dla kodu DBG_RESTART_LOCAL.

Nagłówek wygląda tak:

Nazwa Format Opis
line_start uleb128 wartość początkowa rejestru line automatu stanowego. Nie reprezentuje rzeczywistego wpisu dotyczącego stanowiska.
parameters_size uleb128 liczba zakodowanych nazw parametrów. Powinien być jeden dla każdego parametru metody, z wyjątkiem parametru this metody instancji, jeśli taki istnieje.
parameter_names uleb128p1[parameters_size] indeks ciągu znaków nazwy parametru metody. Zakodowana wartość NO_INDEX oznacza, że dla powiązanego parametru nie jest dostępna żadna nazwa. Deskryptor typu i podpis są implikowane przez deskryptor metody i podpis.

Wartości kodu bajtowego są następujące:

Nazwa Wartość Format Argumenty Opis
DBG_END_SEQUENCE 0x00 (brak) kończy sekwencję informacji debugowania dla code_item.
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff: kwota do dodania do rejestru adresów przesuwa rejestr adresów bez emitowania wpisu pozycji;
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff: kwota, o którą należy zmienić rejestr wiersza. przesuwa rejestr wierszy bez emitowania wpisu pozycji;
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: rejestr, który będzie zawierać lokalny
name_idx: indeks ciągu nazwy
type_idx: indeks typu
wprowadza zmienną lokalną pod bieżącym adresem. Wartość name_idx lub type_idx może być NO_INDEX, aby wskazać, że wartość jest nieznana.
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ć lokalny
name_idx: indeks ciągu nazwy
type_idx: indeks typu
sig_idx: indeks ciągu sygnatury typu
wprowadza zmienną lokalną o sygnaturze typu pod bieżącym adresem. Wartość name_idx, type_idx lub sig_idx może być NO_INDEX, aby wskazać, że ta wartość jest nieznana. (Jeśli jednak sig_idx jest mniejsze niż -1, te same dane można przedstawić wydajniej za pomocą kodu operacji DBG_START_LOCAL).

Uwaga: uwagi dotyczące obsługi podpisów znajdziesz w sekcji „dalvik.annotation.Signature” poniżej.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: register that contained local oznacza bieżącą zmienną lokalną jako wykraczającą poza zakres w bieżącym adresie.
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: zarejestruj się, aby ponownie uruchomić ponownie wprowadza zmienną lokalną pod bieżącym adresem. Nazwa i typ są takie same jak w przypadku ostatniego lokalnego, który był aktywny w określonym rejestrze.
DBG_SET_PROLOGUE_END 0x07 (brak) ustawia rejestr maszyny stanowej prologue_end, co oznacza, że następny dodany wpis pozycji powinien być traktowany jako koniec prologu metody (odpowiednie miejsce na punkt przerwania metody). Rejestr prologue_end jest czyszczony przez dowolny specjalny kod operacji (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (brak) ustawia epilogue_begin rejestr maszyny stanowej, co oznacza, że następny dodany wpis pozycji powinien być traktowany jako początek epilogu metody (odpowiednie miejsce do wstrzymania wykonania przed zakończeniem metody). Rejestr epilogue_begin jest czyszczony przez dowolny specjalny kod operacji (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: indeks ciągu nazwy pliku źródłowego; NO_INDEX jeśli nieznany oznacza, że wszystkie kolejne wpisy numerów wierszy odnoszą się do tej nazwy pliku źródłowego, a nie do nazwy domyślnej określonej w code_item.
Specjalne kody operacji 0x0a…0xff (brak) zwiększa wartości rejestrów lineaddress, wysyła wpis pozycji i czyści rejestry prologue_endepilogue_begin. Opis znajdziesz poniżej.

Specjalne kody operacji

Kody operacji o wartościach z zakresu od 0x0a do 0xff (włącznie) przesuwają rejestry lineaddress o niewielką wartość, a następnie emitują nowy wpis w tabeli pozycji. Wzory na przyrosty są następujące:

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

Odniesienie do elementu 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 ma bezpośrednich adnotacji. 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.
fields_size uint liczba pól oznaczonych tym elementem.
annotated_methods_size uint liczba metod oznaczonych adnotacją przez ten element,
annotated_parameters_size uint liczba list parametrów metod oznaczonych adnotacjami przez ten element.
field_annotations field_annotation[fields_size] (opcjonalny) lista powiązanych adnotacji pól. Elementy listy muszą być posortowane w kolejności rosnącej według parametru field_idx.
method_annotations method_annotation[methods_size] (opcjonalny) lista powiązanych adnotacji metod. Elementy listy muszą być posortowane w kolejności rosnącej według parametru method_idx.
parameter_annotations parameter_annotation[parameters_size] (opcjonalny) lista powiązanych adnotacji parametrów metody. Elementy listy muszą być posortowane w kolejności rosnącej według parametru method_idx.

Uwaga: wszystkie instancje 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 dla tożsamości pola, które jest oznaczane;
annotations_off uint przesunięcie od początku pliku do listy adnotacji dotyczących pola. Przesunięcie powinno odnosić się do lokalizacji 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 method_ids na potrzeby tożsamości metody, która jest opatrywana adnotacjami.
annotations_off uint przesunięcie od początku pliku do listy adnotacji dla metody. Przesunięcie powinno odnosić się do 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 na liście method_ids, który określa tożsamość metody, której parametry są oznaczane;
annotations_off uint przesunięcie od początku pliku do listy adnotacji dla parametrów metody. Przesunięcie powinno odnosić się do lokalizacji w sekcji data. Format danych jest określony przez „annotation_set_ref_list” poniżej.

annotation_set_ref_list

Odwołanie z parametru parameter_annotations_item

Występuje w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
rozmiar uint rozmiar listy (w postaci liczby wpisów),
lista annotation_set_ref_item[size] elementy listy,

annotation_set_ref_item format

Nazwa Format Opis
annotations_off uint przesunięcie od początku pliku do odwołującego się do niego zbioru adnotacji lub 0, jeśli dla tego elementu nie ma adnotacji. 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

Przywoływana z 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 (w liczbie wpisów);
wpisy, annotation_off_item[size] elementy zbioru. 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. Przesunięcie powinno wskazywać lokalizację w sekcji data, a format danych w tej lokalizacji jest określony przez „annotation_item” poniżej.

annotation_item

Przywoływana z elementu annotation_set_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

Nazwa Format Opis
widoczność ubyte zamierzona widoczność tej adnotacji (patrz poniżej);
adnotacja encoded_annotation zakodowane treści adnotacji w formacie opisanym w sekcji „encoded_annotation format” w części „encoded_value encoding” powyżej.

Wartości widoczności

Opcje pola visibilityannotation_item:

Nazwa Wartość Opis
VISIBILITY_BUILD 0x00 mają być widoczne tylko w czasie kompilacji (np. podczas kompilowania innego kodu);
VISIBILITY_RUNTIME 0x01 przeznaczony do wyświetlania w czasie działania
VISIBILITY_SYSTEM 0x02 przeznaczone do wyświetlania w czasie działania, ale tylko w systemie bazowym (a nie w zwykłym kodzie użytkownika).

encoded_array_item

Odniesienie do elementu class_def_item

Występuje w sekcji danych

Wyrównanie: brak (wyrównanie do bajtu)

Nazwa Format Opis
wartość encoded_array bajty reprezentujące zakodowaną wartość tablicy w formacie określonym w sekcji „encoded_array Format” w części „encoded_value Kodowanie” powyżej.

hiddenapi_class_data_item

Ta sekcja zawiera dane o ograniczonych interfejsach używanych przez każdą klasę.

Uwaga: ukryta funkcja interfejsu API została wprowadzona w Androidzie 10.0 i ma zastosowanie tylko do plików DEX klas w ścieżce klasy rozruchowej. Lista flag opisanych poniżej może zostać rozszerzona w przyszłych wersjach Androida. Więcej informacji znajdziesz w artykule o ograniczeniach dotyczących interfejsów innych niż SDK.

Nazwa Format Opis
rozmiar uint całkowity rozmiar sekcji,
offsets uint[] tablica przesunięć indeksowana przez class_idx. Wpis zerowy w tablicy na pozycji class_idx oznacza, że albo nie ma danych dla tego class_idx, albo wszystkie ukryte flagi interfejsu API mają wartość zero. W przeciwnym razie wpis w tablicy jest różny od zera i zawiera przesunięcie od początku sekcji do tablicy ukrytych flag interfejsu API dla tego class_idx.
flagi, uleb128[] połą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 co pola, a metody są kodowane w danych klasy.

Typy flag ograniczeń:

Nazwa Wartość Opis
biała lista, 0 Interfejsy, z których można swobodnie korzystać i które są obsługiwane w ramach oficjalnie udokumentowanego frameworka Androida – indeks pakietów.
szara lista 1 Interfejsy spoza SDK, których można używać niezależnie od docelowego poziomu interfejsu API aplikacji.
zablokuj 2 Interfejsy spoza SDK, których nie można używać niezależnie od docelowego poziomu interfejsu API aplikacji. Dostęp do jednego z tych interfejsów powoduje błąd podczas działania.
greylist‑max‑o 3 Interfejsy spoza SDK, których można używać w Androidzie 8.x i starszych wersjach, chyba że są objęte ograniczeniami.
greylist‑max‑p 4 Interfejsy inne niż SDK, których można używać w Androidzie 9.x, chyba że są ograniczone.
greylist‑max‑q 5 Interfejsy spoza SDK, których można używać w Androidzie 10.x, o ile nie są objęte ograniczeniami.
greylist‑max‑r 6 Interfejsy spoza SDK, których można używać w Androidzie 11.x, chyba że są objęte ograniczeniami.

Adnotacje systemowe

Adnotacje systemowe służą do reprezentowania różnych informacji o klasach (oraz metodach i polach). Dostęp do tych informacji jest zwykle uzyskiwany pośrednio przez kod klienta (inny niż systemowy).

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 powiązania, dołączona jest adnotacja AnnotationDefault.

Nazwa Format Opis
wartość Adnotacja domyślne powiązania dla 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

Wyświetlanie na zajęciach

Do każdej klasy dołączona jest adnotacja EnclosingClass, która jest zdefiniowana jako element innej klasy lub jest anonimowa, ale nie jest zdefiniowana w treści metody (np. syntetyczna klasa wewnętrzna). Każda klasa, która ma tę adnotację, musi mieć też adnotację InnerClass. Klasa nie może mieć jednocześnie adnotacji EnclosingClassEnclosingMethod.

Nazwa Format Opis
wartość Kategoria klasa, która jest najbliższa tej klasie pod względem leksykalnym;

dalvik.annotation.EnclosingMethod

Wyświetlanie na zajęciach

Do każdej klasy zdefiniowanej w treści metody dołączona jest adnotacja EnclosingMethod. Każda klasa, która ma tę adnotację, musi mieć też adnotację InnerClass. Dodatkowo klasa nie może 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

Wyświetlanie na zajęciach

Do każdej klasy InnerClass zdefiniowanej w zakresie leksykalnym definicji innej klasy jest dołączona adnotacja. Każda klasa, która ma tę adnotację, musi mieć też adnotację EnclosingClass lub EnclosingMethod.

Nazwa Format Opis
nazwa Ciąg znaków pierwotnie zadeklarowana prosta nazwa tej klasy (bez prefiksu pakietu). Jeśli zajęcia są anonimowe, nazwa to null.
accessFlags int pierwotnie zadeklarowane flagi dostępu klasy (które mogą się różnić od flag efektywnych z powodu niezgodności między modelami wykonania języka źródłowego a docelowej maszyny wirtualnej);

dalvik.annotation.MemberClasses

Wyświetlanie na zajęciach

Do każdej klasy, która deklaruje klasy składowe, dołączona jest adnotacja MemberClasses. (Klasa składowa to bezpośrednia klasa wewnętrzna, która ma nazwę).

Nazwa Format Opis
wartość Klasa[] tablica klas elementów

dalvik.annotation.MethodParameters

Pojawia się w metodach

Uwaga: ta adnotacja została dodana po Androidzie 7.1. W starszych wersjach Androida będzie on ignorowany.

Adnotacja MethodParameters jest opcjonalna i może służyć do podawania metadanych parametrów, takich jak nazwy parametrów i modyfikatory.

Adnotację można bezpiecznie pominąć w metodzie lub konstruktorze, gdy metadane parametru nie są wymagane w czasie działania. java.lang.reflect.Parameter.isNamePresent() można użyć do sprawdzenia, czy dla parametru są dostępne metadane, a powiązane metody odbicia, takie jak java.lang.reflect.Parameter.getName(), w przypadku braku informacji wrócą w czasie działania do domyślnego zachowania.

Podczas uwzględniania metadanych parametrów kompilatory muszą zawierać informacje o wygenerowanych klasach, takich jak wyliczenia, ponieważ metadane parametrów zawierają informacje o tym, czy parametr jest syntetyczny lub wymagany.

Adnotacja MethodParameters opisuje tylko poszczególne parametry metody. Dlatego kompilatory mogą całkowicie pominąć adnotację w przypadku konstruktorów i metod, które nie mają parametrów, ze względu na rozmiar kodu i wydajność w czasie działania.

Tablice opisane poniżej muszą mieć taki sam rozmiar jak method_id_itemstruktura dex powiązana z metodą. W przeciwnym razie w czasie działania programu zostanie zgłoszony wyjątek 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.

Ponieważ MethodParameters opisuje wszystkie parametry formalne metody, nawet te, które nie są jawnie ani niejawnie zadeklarowane w kodzie źródłowym, rozmiar tablic może się różnić od informacji o sygnaturze lub innych 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 odbiornika adnotacji typu, które nie występują w rzeczywistym podpisie metody.

Nazwa Format Opis
nazwy, Ciąg znaków[] Nazwy parametrów formalnych powiązanej metody. Tablica nie może mieć wartości null, ale musi być pusta, jeśli nie ma parametrów formalnych. Wartość w tablicy musi mieć wartość null, jeśli parametr formalny o tym indeksie nie ma nazwy.
Jeśli ciągi nazw parametrów są puste lub zawierają znaki „.”, „;”, „[” lub „/”, w czasie działania programu zostanie zgłoszony błąd java.lang.reflect.MalformedParametersException.
accessFlags int[] Flagi dostępu parametrów formalnych powiązanej metody. Tablica nie może mieć wartości null, ale musi być pusta, jeśli nie ma parametrów formalnych.
Wartość jest maską bitową o tych wartościach:
  • 0x0010 : final, parametr został zadeklarowany jako finalny
  • 0x1000 : synthetic, the parameter was introduced by the compiler
  • 0x8000 : wymagany, parametr jest syntetyczny, ale wynika też ze specyfikacji języka
Jeśli jakiekolwiek bity są ustawione poza tym zbiorem, w czasie działania programu zostanie zgłoszony wyjątek java.lang.reflect.MalformedParametersException.

dalvik.annotation.Signature

Wyświetla się w przypadku klas, pól i metod

Adnotacja Signature jest dołączana do każdej klasy, pola lub metody, które są zdefiniowane za pomocą bardziej złożonego typu niż ten, który można przedstawić za pomocą type_id_item. Format .dex nie określa formatu podpisów. Ma on jedynie umożliwiać reprezentowanie podpisów wymaganych przez język źródłowy do prawidłowego wdrożenia semantyki tego języka. 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). Dlatego każde użycie podpisu powinno być zapisane w taki sposób, aby nie zakładać, że otrzymywane są tylko prawidłowe podpisy, i wyraźnie zabezpieczać się przed możliwością napotkania podpisu nieprawidłowego pod względem składni.

Ciągi sygnatur zwykle zawierają dużo powielonej treści, dlatego adnotacja Signature jest definiowana jako tablica ciągów tekstowych, w której powielone elementy naturalnie odnoszą się do tych samych danych bazowych, a sygnatura jest traktowana jako połączenie wszystkich ciągów tekstowych w tablicy. Nie ma reguł dotyczących rozdzielania podpisu na osobne ciągi znaków. Zależy to całkowicie od narzędzi, które generują pliki .dex.

Nazwa Format Opis
wartość Ciąg znaków[] sygnatura tej klasy lub tego elementu w postaci tablicy ciągów znaków, które należy połączyć ze sobą;

dalvik.annotation.Throws

Pojawia się w metodach

Do każdej metody, która może zgłaszać co najmniej 1 typ wyjątku, jest dołączona adnotacja Throws.

Nazwa Format Opis
wartość Klasa[] tablica zgłaszanych typów wyjątków,