2013-07-18 31 views
25

Dalvik có giới hạn nổi tiếng này về số phương pháp mà nó có thể có trong một tệp .dex duy nhất (khoảng 65.536 trong số đó). Câu hỏi của tôi là liệu các phương thức kế thừa (nhưng không ghi đè) có được tính vào giới hạn này hay không.Các phương pháp kế thừa có được tính vào giới hạn phương pháp Dex trong Android không?

Để làm cho mọi việc cụ thể, giả sử tôi có:

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

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

Theo mục đích của giới hạn 65.536 phương pháp, không đếm này như thêm một phương pháp, hoặc thêm 4? (Hoặc, tôi đoán, để có những điều để kết luận hợp lý của họ, không tính này là 1 phương pháp hoặc 52 phương pháp, xem xét rằng java.lang.Object mang 12 phương pháp cùng quá). Là một nền tảng, tôi có một số lượng không đáng kể các lớp được tạo ra với một số điểm chung, và tôi cũng gặp phải giới hạn về phương pháp, vì vậy tôi tự hỏi liệu nó có đáng để cố gắng tóm tắt một số trong các lớp đó hay không. vào một hệ thống phân cấp lớp để mua một chút thời gian.

+1

Vì bạn có thể thay đổi mức độ hiển thị của phương pháp, sẽ không có ý nghĩa rằng nó sẽ cần phải đếm tất cả chúng? [Xem ở đây cho định dạng dex] (http://www.retrodev.com/android/dexformat.html). –

+2

Liên kết retrodev là một kỹ thuật đảo ngược lỗi thời đã lỗi thời của phiên bản prerelease của định dạng tệp dex. Hãy thử để biết nguồn có thẩm quyền và cập nhật hơn. – danfuzz

+0

404 trên dex-format.html –

Trả lời

15

Phương pháp kế thừa nhưng không được ghi đè chỉ tính vào giới hạn phương pháp nếu nó được tham chiếu (được gọi).

Trong ví dụ của bạn, giả sử bạn có đoạn mã sau

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

Trong trường hợp này, bạn đang đề cập đến Foo.foo(), mà đã có một tài liệu tham khảo, do sự định nghĩa rõ ràng. Giả sử 5 lớp này là các lớp duy nhất trong tệp dex, bạn sẽ có tổng cộng 2 tham chiếu phương thức *. Một cho main.main (String []), và một cho Foo.foo().

Thay vào đó, chúng ta hãy nói rằng bạn có đoạn mã sau

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

Trong trường hợp này, vì phương pháp foo cho mỗi lớp con được thực sự tham chiếu, họ sẽ tính vào giới hạn phương pháp của bạn. Tệp dex của bạn sẽ có 5 tham chiếu phương thức *.

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

* Số này không hoàn toàn chính xác, nó không tính đến các phương thức của hàm tạo được thêm vào mỗi lớp đằng sau hậu trường. Mỗi hàm tạo gọi hàm tạo của lớp bậc trên, vì vậy chúng tôi cũng có tham chiếu đến hàm tạo của đối tượng, cho tổng cộng 6 tham chiếu phương thức bổ sung trong mỗi trường hợp, cho biết số phương thức tương ứng là 8 và 11.


Nếu nghi ngờ, bạn có thể thử ra các kịch bản khác nhau và sử dụng chức năng bãi chứa nguyên baksmali để xem những gì các danh sách phương pháp trong file dex thực sự chứa.

ví dụ:

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

Sau đó, trong tệp kết xuất, hãy tìm "phần method_id_item". Đây là danh sách các tham chiếu phương thức mà giới hạn 64k áp dụng cho.

+2

Không phải hàm tạo cũng được tính là tham chiếu phương thức? Vì vậy, sẽ không làm tăng số lượng các phương pháp tham khảo trong ví dụ của bạn? – snrlx

+0

@nvrmnd, vâng. Đó là một điểm tốt. Tôi sẽ cập nhật câu trả lời cho phù hợp. Cảm ơn! – JesusFreke

+0

Các phương pháp bên trong các tệp .SO hoặc mã JNI có bao giờ được tính vào giới hạn này không? – skygeek

Các vấn đề liên quan