2010-01-07 24 views
6

Tôi có một ứng dụng Android (java) mà đã làm việc tốt khi biên soạn với 1.6 SDK Android sử dụng đoạn mã sau từ lớp android.provider.Contacts:Đây có phải là phản ánh và mức độ nào không?

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL; 

Khi 2.0 SDK lại phát ra, android lớp .provider.Contacts đã bị khấu hao và được thay thế bằng android.provider.ContactsContract. Để có được một chương trình để làm việc trên cả 1.6 và 2.0, tôi biên soạn dưới 1.6 với sự thay đổi sau đây:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL; 
… 
try { 
    Class<?> c = Class.forName("android.provider.ContactsContract$PhoneLookup"); 
    baseUri = (Uri) c.getField("CONTENT_FILTER_URI").get(baseUri); 
} 
    catch (Exception e) {   
} 

Kể từ khi tôi đã được biên soạn dưới 1.6, tôi không thể nhập khẩu android.provider.ContactsContract vì nó là một lớp chỉ biết đến 2.0. Đây có phải là sự phản ánh và mức độ nào không?

Sau khi đọc phần "Phản ánh" của "Ngôn ngữ lập trình Java" (tôi nên làm trước), bây giờ tôi hiểu rõ bạn có thể làm gì với sự phản chiếu nhưng định nghĩa ngắn gọn về phản chiếu không phải là dễ dàng đi qua. Câu trả lời của bạn đã giúp làm rõ những gì đã nhắc câu hỏi của tôi - rằng một khi một lớp đã được phản ánh, và một thể hiện của lớp được tạo ra bằng cách sử dụng sự phản chiếu, bạn có thể tương tác với cá thể như thể lớp đã được new'ed.

Đây là nỗ lực ít ỏi của tôi tại một định nghĩa ngắn gọn rằng còn lâu mới hoàn hảo và tôi chắc chắn tôi sẽ cần phải chỉnh sửa như tôi tìm hiểu thêm:

Reflection là gián tiếp, năng động điều tra, xử lý hoặc gọi của các đối tượng lớp bằng cách sử dụng các đối tượng lớp có trong lớp java.lang.reflect hoặc lớp Class hoặc Package yêu cầu ban đầu truy cập vào lớp bằng cách sử dụng một tên chuỗi đầy đủ.

+3

Lưu ý rằng ngay cả mặc dù đó URI bị phản đối trong 2.0, các chức năng vẫn nên tồn tại trong khuôn khổ một thời gian (mặc dù đôi khi Android có cách giải thích riêng của nó về từ "không được chấp nhận"). –

+0

Bạn đúng là nó vẫn tồn tại ngoại trừ chức năng dưới 2.0 không hoạt động. Địa chỉ liên hệ được yêu cầu không được truy xuất lại.Tôi không thể nhớ nếu nó không trả về liên lạc hoặc liên lạc "Thẻ liên lạc của tôi" mỗi lần. – fupsduck

+0

Thay vì mã trên, và dựa vào ngoại lệ ClassNotFound, bạn có thể chủ động kiểm tra phiên bản Android bạn đang chạy trong một thuộc tính môi trường, và sau đó chuyển đổi gọi hàm phụ trả về BaseURI –

Trả lời

6

Tôi tin rằng đó là định nghĩa của Java reflection (more on Android reflection for multiple-version compatibility). Tôi không chắc chắn ý bạn là gì "bằng mức độ nào"; nó chỉ là.

+0

phải - dù là vậy hay không. Trong trường hợp này, nó là. – nont

+0

Bởi mức độ nào tôi muốn nói là tất cả đều có sự phản ánh? JasperE nói ví dụ của tôi chỉ là một hình thức ngụ ý có nhiều sự phản ánh hơn là chỉ đơn giản là "tự động yêu cầu sự sẵn có của một phương pháp". – fupsduck

+0

Vâng, có nhiều thứ bạn có thể làm với sự phản chiếu khi cần thiết, chẳng hạn như tạo các đối tượng hoặc gọi các phương thức. Bạn cũng có thể sử dụng sự phản chiếu chỉ để khám phá những biến thành viên và các phương thức lớp nào mà Class có. –

4

Tự động yêu cầu tính khả dụng của phương thức là một dạng phản ánh, có.

+0

Vì vậy, dòng dưới cùng, bất cứ lúc nào bạn truy cập các đối tượng bằng cách sử dụng tên đầy đủ của họ, nó phản ánh nhưng có các hình thức phản chiếu khác? – fupsduck

+0

Không. Reflection đang truy cập các đối tượng kiểu từ các chuỗi hoặc các kiểu giá trị khác. Đó là, nếu bạn có thể giữ tên của lớp hoặc phương thức trong một biến chuỗi và nhận được nó. Nó phản ánh vì trình biên dịch không biết/kiểm tra giá trị của var đó. – helios

+0

Hoặc có thể phản ánh = truy cập thông tin loại khi chạy. – helios

1

Đó là sự phản ánh.

Nếu CONTENT_FILTER_URI là trường tĩnh cuối cùng, thì bạn nên sử dụng get(null) thay vì get(baseUri) vì bạn không gọi một đối tượng.

Sửa

tôi một chút bối rối bởi mã của bạn. Khi tôi hiểu đoạn mã của bạn, trước tiên bạn chỉ định Contacts.Phones.CONTENT_FILTER_URL cho URL baseUri, thì bạn phản ánh trường CONTENT_FILTER_URI trên lớp PhoneLookup và đọc giá trị trường đó từ cá thể URL được lưu trữ trong baseUri - chỉ để gán giá trị cho baseUri một lần nữa! Typo hoặc phòng để cải thiện?

+0

Cách tôi hiểu nó là nhiệm vụ ban đầu là cần thiết khi chương trình chạy dưới 1,6 và nhiệm vụ được phản ánh là cần thiết khi chạy dưới 2.0. Kể từ khi một ngoại lệ được ném xuống dưới 2.0, nhiệm vụ ban đầu chiếm ưu thế khi chạy dưới 1.6. – fupsduck

+0

Loại - ngoại lệ được ném dưới 1,6 không 2.0 vì lớp android.provider.ContactsContract không tồn tại dưới 1,6. – fupsduck

+0

Loại - trên = Typo trong nhận xét đầu tiên. – fupsduck

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