Подтвердить что ты не робот

Унаследованные методы учитывают ограничение на Dex в Android?

Dalvik имеет это известное ограничение на количество методов, которые он может иметь в одном файле .dex (около 65536 из них). Мой вопрос заключается в том, учитываются ли унаследованные (но не переопределенные) методы против этого предела или нет.

Чтобы сделать вещи конкретными, предположим, что у меня есть:

public class Foo {
  public int foo() {
    return 0;
  }
}

public class A extends Foo { }
public class B extends Foo { }
public class C extends Foo { }

В целях ограничения метода 65536 это считается добавлением одного метода или добавлением 4? (Или, я полагаю, чтобы довести их до логического завершения, считается ли это 1 метод или 52 метода, учитывая, что java.lang.Object также использует 12 методов).

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

4b9b3361

Ответ 1

Унаследованный, но не переопределенный метод учитывает только предел метода, если он когда-либо ссылается (называется).

В вашем примере предположим, что у вас есть следующий фрагмент кода

public class main {
    public static void main(String[] args) {
        Foo foo = new A();
        foo.foo();
    }
}

В этом случае вы ссылаетесь на Foo.foo(), у которого уже есть ссылка, из-за явного определения. Предполагая, что эти 5 классов являются единственными классами в файле dex, у вас будет всего 2 ссылки на методы *. Один для main.main(String []) и один для Foo.foo().

Вместо этого скажем, у вас есть следующий код

public class main {
    public static void main(String[] args) {
        A a = new A();
        a.foo();

        B b = new B();
        b.foo();

        C c = new C();
        c.foo();
    }
}

В этом случае, поскольку метод foo для каждого подкласса на самом деле ссылается, они будут рассчитывать против вашего ограничения метода. Ваш файл dex будет содержать 5 ссылок на методы *.

  • main.main(String [])
  • Foo.foo()
  • A.foo()
  • B.foo()
  • C.foo()

* Этот счет не совсем точен, он не учитывает методы конструктора, которые добавляются в каждый класс за кулисами. Каждый конструктор вызывает свой конструктор суперкласса, поэтому мы также имеем ссылку на конструктор Object, в общей сложности 6 дополнительных ссылок на методы в каждом случае, давая количество меток 8 и 11 соответственно.


Если вы сомневаетесь, вы можете попробовать различные сценарии и использовать функциональность baksmali raw dump, чтобы увидеть, что на самом деле содержит список методов в файле dex.

например.

javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex

И затем в файле дампа найдите "раздел method_id_item". Это список ссылок на методы, к которым применяется ограничение 64k.