2015-01-17 18 views
5

Tôi cần phương pháp proxy trên các lớp chế độ xem khác nhau trong Khung giao diện người dùng Android như TextView. Riêng TextView#setText(int resId). Phương thức này không phải là một phần của giao diện. Do đó, Java Proxy sẽ không hoạt động vì nó chỉ hoạt động đối với giao diện. Tôi cần sử dụng thao tác bytecode.Phương pháp cuối cùng của Proxy Trong lớp học cuối cùng

Tôi đã tìm thấy thư viện có tên là dexmaker có vẻ đầy hứa hẹn. Tôi giả định rằng tôi cần phải thực hiện thao tác mã byte thời gian chạy vì lớp Android View chỉ thực sự có sẵn trên thiết bị. Dexmaker có thể ủy quyền các phương thức công khai trên các lớp cụ thể. Sau đó, tôi nhận thấy rằng TextView#setText(int resId) là không thể giải thích final. Bản thân lớp TextView không phải là cuối cùng.

Tôi nghĩ rằng tôi có thể ngã ba dexmaker để hỗ trợ các phương pháp cuối cùng trong các lớp học không phải cuối cùng. Điều này có thể không? Tôi không muốn bắt đầu dự án này nếu không. Nó sẽ là một chiến thắng lớn cho thư viện của tôi mặc dù bởi vì các nhà phát triển sẽ không cần phải có lớp con, giao diện, hoặc các cuộc gọi phương thức tĩnh thủ công cho quan điểm của họ. Thư viện của tôi cần biết khi nào văn bản được đặt trên Chế độ xem cụ thể. Một proxy là mẫu thiết kế hoàn hảo cho việc này.

+1

Ảnh ngẫu nhiên (vì nó không được đề cập): Bộ đệm bố cục cho phép [đặt một lớp nhà máy] (http://developer.android.com/reference/android/view/LayoutInflater. html # setFactory2 (android.view.LayoutInflater.Factory2)) có thể là những gì bạn đang theo dõi. Điều này được sử dụng trong [probe] (https://github.com/lucasr/probe/), nơi nhà máy tự động tạo proxy bằng cách sử dụng dexmaker để chặn các cuộc gọi. –

+0

Một phần của thư viện của tôi thực sự sử dụng kỹ thuật nhà máy thổi phồng bố cục. Bạn đang nói rằng bạn có thể thiết lập một proxy có trên các đối tượng xem được tạo ra thông qua dexmaker? – jophde

+0

Cảm ơn Stefan rất nhiều. Nguồn Probe chính xác là những gì tôi cần :). Nếu tôi hiểu một cách chính xác Probe tạo ra các lớp View hoàn toàn mới để giới hạn của trình rút gọn proxybuild không thể xử lý các phương thức cuối cùng không phải là một vấn đề? Từ tài liệu về trình soạn thảo ProxyBuilder: "Quá trình này chỉ hoạt động đối với các lớp có mức độ hiển thị công khai và được bảo vệ". – jophde

Trả lời

2

Theo như tôi biết, điều này là không thể trên Android.

Dexmaker tạo tệp dex chứa các lớp mới. Các lớp này sau đó được thêm vào một ứng dụng bằng cách sử dụng bộ nạp lớp dex. Tuy nhiên, các tệp dex như vậy có thể không được sử dụng để thay thế các lớp, chỉ để thêm các lớp con mới hoạt động như một proxy.

Trong ý nghĩa này, dexmaker là khá giống như cglib hơn javassist.

Lưu ý rằng Android không cung cấp khả năng thiết bị tương tự như Jvm thông thường, nơi bạn có thể sử dụng các lớp và phương thức cuối cùng theo định nghĩa lại lớp thông qua tác nhân. Android không được Android cung cấp: http://developer.android.com/reference/android/app/Instrumentation.html

2

Mục đích của "cuối cùng" là phương pháp không thể bị ghi đè. Điều đó có hiệu quả ngăn chặn proxy bằng cách mở rộng. Tuy nhiên, bạn vẫn có thể ủy quyền bằng cách gói, cách Spring xử lý nó.

Đó là một lý do tại sao cách tốt nhất là tách riêng giao diện khỏi triển khai.

Về cụ thể hơn ...

// This snip is not supposed to be functional, only to demonstrate a concept 
interface TextViewInterface { 
    void setText (int resId); 
} 

class TextView implements TextViewInterface { 
    public final void setText (int resId) { 
    ... snip ... 
    } 
} 

class Proxy$TextView implements TextViewInterface 
extends View { // Added this for Android hierarchy 
    private TextView textView; 

    public void setText (int resId) { 
     textView.setText(resId); 
    } 
} 

Liệu sự giúp đỡ này?

+0

Điều này sẽ hoạt động bình thường nhưng các đối tượng cần phải đi vào Hệ thống phân cấp cây Android View mà chỉ chấp nhận các lớp con của View hoặc ViewGroup và tôi chắc chắn trường hợp được sử dụng ở các vị trí. Nếu tôi mở rộng từ TextView thì phương thức giao diện có can thiệp vào phương thức lớp không? – jophde

+0

Yea nó sẽ không biên dịch nếu tôi cũng mở rộng TextView. Nếu chỉ họ sử dụng giao diện ... – jophde

+0

Cơ chế giao diện cho phép bạn quấn phương thức lớp. Bạn có thể mở rộng View (gọi nó là MyTextViewProxy) và bọc TextView, cung cấp bất cứ điều gì mở rộng Xem là chấp nhận được. Tôi đã cập nhật ví dụ ở trên để hiển thị Chế độ xem mở rộng. –

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