2013-07-18 4 views
25

Dalvik ma to znane ograniczenie liczby metod, jakie może mieć w jednym pliku .dex (około 65 536 z nich). Moje pytanie brzmi, czy odziedziczone (ale nie przesłonięte) metody liczą się z tym limitem, czy nie.Czy odziedziczone metody liczą się z limitem metody Dex w systemie Android?

Żeby beton, załóżmy mam:

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

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

Do celów limitu 65.536 metoda robi to liczyć jako dodając jedną metodę, lub dodając 4? (Albo, jak sądzę, do rzeczy logicznych do wniosku, czy to liczy się jako 1 metoda lub 52 metody, biorąc pod uwagę, że java.lang.Object przynosi również 12 metod).

Jako tło, mam nietrywialną liczbę wygenerowanych klas z pewnym podobieństwem, a także podskakuję w stosunku do limitu metody, więc zastanawiam się, czy warto spróbować streścić niektóre z nich w hierarchię klas, aby kupić trochę czasu.

+1

Skoro można zmienić widoczność metody, czy nie ma sensu wymaganie zliczenia wszystkich? [Zobacz tutaj w formacie dex] (http://www.retrodev.com/android/dexformat.html). –

+2

Łącze retrodv jest do żałośnie przestarzałej inżynierii odwrotnej wersji przedpremierowej formatu pliku dex. Wypróbuj , aby uzyskać bardziej wiarygodne i aktualne źródło. – danfuzz

+0

404 na dex-format.html –

Odpowiedz

15

Metoda odziedziczona, ale nie nadpisywana, liczy się tylko z limitem metody, jeśli kiedykolwiek zostanie odwołana (wywołana).

W przykładzie, powiedzmy, że masz następujący kawałek kodu

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

W tym przypadku, do którego się odnosimy Foo.foo(), która ma już odniesienia, z powodu wyraźnej definicji. Zakładając, że te 5 klas są jedynymi klasami w pliku z danymi osobowymi, będziesz mieć w sumie 2 odwołania do metod *. Jeden dla main.main (String []), a drugi dla Foo.foo().

Zamiast, powiedzmy masz następujący kod

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(); 
    } 
} 

W tym przypadku, ponieważ metoda foo dla każdej podklasy jest rzeczywiście odwoływać, będą wliczane do limitu metody. Twój plik dex będzie miał 5 odwołań do metod *.

  • main.main (ciąg [])
  • Foo.foo()
  • A.foo()
  • B.foo()
  • C.foo()

* Ta liczba nie jest dokładna, nie uwzględnia metod konstruktora dodawanych do każdej klasy za kulisami. Każdy konstruktor wywołuje jego konstruktor klasy superklasy, więc mamy również odniesienie do konstruktora obiektów, w sumie 6 dodatkowych odwołań metod w każdym przypadku, podając liczbę metod odpowiednio 8 i 11.


W razie wątpliwości, można wypróbować różne scenariusze i wykorzystywać funkcjonalność zrzutu surowego baksmali, aby zobaczyć, co lista metoda w pliku dex rzeczywiście zawiera.

np.

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

A następnie, w pliku zrzutu, poszukaj "section_id_item section". Jest to lista odwołań do metod, do których odnosi się limit 64 KB.

+2

Czy konstruktorzy nie są również licznikami metod? Czy nie zwiększyłoby to liczby odwołań do metod w Waszych przykładach? – snrlx

+0

@nvrmnd, tak. To dobry punkt. Odpowiednio zaktualizuję odpowiedź. Dzięki! – JesusFreke

+0

Czy metody w plikach .SO lub JNI kiedykolwiek wliczają się do tego limitu? – skygeek