2016-12-04 4 views
3

Мне было интересно, считаются ли методы, написанные на родном C++, в счете метода файлов Dex для ограничения количества меток метода Dex.Являются ли родные методы C++ подсчитаны в методе файла dex?

Если да, то сколько методов добавляется к счету Dex, если добавлен 1 собственный метод?

И сколько методов делает метод Java добавить к графе DEX, потому что я, кажется, не имеет солидное число в каждой сборке я делаю ...

ответ

2

Чтобы получить ответы, которые мы должны ходить через .Dex Format. В нашем случае наиболее интересной является массив method_ids:

список идентификаторов методов. Это идентификаторы для всех методов , на которые ссылается данный файл, независимо от того, указан ли он в файле. Этот список должен быть отсортирован, где определяющий тип (по type_id индексом) является крупный заказ, имя метода (по string_id индексом) является промежуточным порядка и способа-прототипа (по proto_id индекса) является несовершеннолетним заказ. Список не должен содержать дубликатов записей.

Вне зависимости от того факта, что количество записей массива хранятся в виде 32-разрядного целого числа без знака (см method_ids_size поля) на практике этого массив не может содержать более 65536 записи. Это связано с тем, что операнд method_id команды dex invoke-xxxx - это 16-битный объект и должен быть действительным индексом в method_ids. В результате записи с индексами больше 65535 были бы недоступны по байт-коду. Все это приводит к известной проблеме «64K Methods».

Так, как говорят документы - method_ids имеет по одной записи на каждый метод, определенный этим dex, а также для внешних, которые передаются кодом определенных методов.

Следовательно, каждый раз, когда вы добавляете код, как:

public native void foo(); 

к одному из ваших классов - Вы получаете одну дополнительную запись в method_ids. Это также относится к объявлениям методов abstract. Затем, каждый раз, когда вы добавляете реализацию некоторого регулярного метода, как:

public void baz() { 
    /* ... */ 
} 

вы получаете один новый рекорд для себя и записей baz() для всех методов, на которые ссылается baz() и не добавляются к method_ids еще.

Исходный код не влияет на содержание dex, так как все источники C/C++ скомпилированы в машинный код, который распространяется через файлы .so. Они используют формат ELF, который имеет свои собственные ограничения и абсолютно независим от DEX.