Android Вызов метода Multidex - PullRequest
0 голосов
/ 28 мая 2020

У меня вопрос по Multidex в Android. Если приложение состоит из нескольких файлов Dex (classes.dex, classes2.dex), как вызов работает в байт-коде?

Поскольку идентификаторы методов, указанные в инструкциях вызова, по-прежнему 16-разрядные (от https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions):

invoke-direct {v C , vD, vE, vF, vG}, meth@BBBB

A: количество слов аргумента (4 бита), B: индекс ссылки на метод (16 бит), C .. G: регистры аргументов (по 4 бита)

Итак, как метод, определенный в ссылке classes2.dex или, что более важно, вызывает метод, определенный в classes.dex или classes3.dex?

С уважением,

Лоран

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Согласно: «В принципе, как он узнает смещение кода и как он узнает, в каком dex-файле находится метод?»

Учтите, что эти dex-файлы являются «промежуточными» файлами, интерпретируемыми или скомпилированными с помощью виртуальной машины (ART) или компилятора (dex2oat). Это означает, что нет "смещения" или таблицы перемещения, как в файлах ELF или MACH-O.

Как объяснил Antimony, идентификатор в вызове invoke - это просто индекс в таблице ref одного файла dex. Эта таблица ссылок сопоставляет имя класса, имя метода и подпись к индексу. В итоге виртуальная машина загружает все файлы dex и создает в памяти таблицу классов и методов. Если вызывается invoke (..) get, он проверяет справочную таблицу файла dex и выбирает метод тарета, имя класса и подпись. Теперь он ищет эти три значения в памяти и вызывает.

Пожалуйста, учтите, что вам нужно иметь дело с виртуальной машиной, которая переводит промежуточный язык в архитектурно-зависимый код по адресу: * Runtime (режим интерпретатора) * Runtime, но при необходимости кеширует («Как раз вовремя») * Во время установки вашего приложения («Опережая время»)

Проверьте: https://source.android.com/devices/tech/dalvik/configure

Вот еще один пример, но используя JVM (означает java коды операций):

    public final class org.chickenhook.binderfuzzy.BuildConfig
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#32         // java/lang/Object."<init>":()V
   #2 = String             #33            // true
   #3 = Methodref          #34.#35        // java/lang/Boolean.parseBoolean:(Ljava/lang/String;)Z
   #4 = Fieldref           #5.#36         // org/chickenhook/binderfuzzy/BuildConfig.DEBUG:Z
   #5 = Class              #37            // org/chickenhook/binderfuzzy/BuildConfig
   #6 = Class              #38            // java/lang/Object
   #7 = Utf8               DEBUG
   #8 = Utf8               Z
   #9 = Utf8               APPLICATION_ID
  #10 = Utf8               Ljava/lang/String;
  #11 = Utf8               ConstantValue

Здесь вы можете увидеть «постоянный пул». В INDEX # 3 у вас есть ссылка на метод java / lang / Boolean.parseBoolean: (Ljava / lang / String;) Z (как я уже сказал, класс, метод и подпись). VM, jit или aot считывает это значение и проверяет память во время выполнения на предмет наличия класса в таблице, где представлены все классы всех промежуточных файлов.

Важно то, что путь к классам указывает на все необходимые промежуточные звенья. В противном случае вы получите исключение ClassNotFound. Он запоминает небольшой бит для компоновщиков времени выполнения, ищущих имена символов и заполняющих таблицу перемещения двоичного файла да, но технически он завершается иначе.

0 голосов
/ 28 мая 2020

Индекс метода - это просто индекс таблицы, включенной в другом месте файла dex, который дает имя метода, подпись типа и класс. Этот метод может быть определен где угодно, даже в другом dex-файле или быть частью одного из системных классов. Любой конкретный файл dex может ссылаться только на 65 тыс. Методов, но несколько файлов dex могут ссылаться на разные наборы методов из-за включения их собственных таблиц дескрипторов методов.

...