Ánh xạ giữa tài nguyên android và ID tài nguyên hoạt động như thế nào?


77

Điều kỳ diệu đối với Android là xác định được tài nguyên thích hợp chỉ thông qua R.id.XXX .

AFAIK, các tài nguyên được biên dịch sang định dạng nhị phân, vậy logic ánh xạ này hoạt động như thế nào?

Có thể nó hoạt động như thế này:

Ví dụ: trong layout1.xml , chúng tôi có:

<Button android:id="@+id/button1" >

và AAPT sẽ tạo điều này trong R.java:

public static final int button1=0x7f05000b;

Khi * .apk được tạo, @ + id / button1 với được thay thế bằng "0x7f05000b".

Do đó, khi chúng ta gọi:

findViewById(R.id.button1);

về cơ bản chúng tôi vẫn thực hiện tìm kiếm dựa trên ID, mặc dù ID là một số như 0x7f05000b.

Cảm ơn!

THÊM VÀO

Điều tôi thực sự muốn biết là số nguyên id tài nguyên được phân tích cú pháp thành nội dung tài nguyên như thế nào? Nói cách khác, thời gian chạy Android định vị nội dung tài nguyên với id tài nguyên là đầu mối duy nhất như thế nào?

Ví dụ, làm thế nào một bức tranh có thể vẽ được tìm thấy với id tài nguyên? Hoặc giá trị chuỗi được tìm thấy với id tài nguyên như thế nào?

Câu trả lời:


194

Tại thời điểm xây dựng, công cụ aapt thu thập tất cả các tài nguyên bạn đã xác định (mặc dù các tệp riêng biệt hoặc các định nghĩa rõ ràng trong tệp) và gán ID tài nguyên cho chúng.

ID tài nguyên là một số 32 bit có dạng: PPTTNNNN. PP là gói tài nguyên dành cho; TT là loại tài nguyên; NNNN là tên của tài nguyên trong loại đó. Đối với tài nguyên ứng dụng, PP luôn là 0x7f.

Các giá trị TT và NNNN được gán bởi aapt một cách tùy ý - về cơ bản đối với mỗi kiểu mới, số có sẵn tiếp theo được gán và sử dụng (bắt đầu bằng 1); tương tự như vậy đối với mỗi tên mới trong một loại, số có sẵn tiếp theo được gán và sử dụng (bắt đầu bằng 1).

Vì vậy, nếu chúng ta có các tệp tài nguyên này được xử lý bởi aapt theo thứ tự sau:

layout/main.xml
drawable/icon.xml
layout/listitem.xml

Kiểu đầu tiên chúng ta thấy là "bố cục" để được đưa ra TT == 1. Tên đầu tiên dưới kiểu đó là "chính" để được cung cấp NNNN == 1. ID tài nguyên cuối cùng là 0x7f010001.

Tiếp theo, chúng ta thấy "drawable" được đưa ra TT == 2. Tên đầu tiên cho kiểu đó là "icon" để nhận NNNN == 1. ID tài nguyên cuối cùng là 0x7f020001.

Cuối cùng, chúng ta thấy một "bố cục" khác có TT == 1 như trước. Tên này có tên mới "listitem" để nhận giá trị tiếp theo NNNN == 2. ID tài nguyên cuối cùng là 0x7f010002.

Lưu ý rằng aapt theo mặc định không cố gắng giữ cho các số nhận dạng này giống nhau giữa các bản dựng. Mỗi khi tài nguyên thay đổi, tất cả chúng đều có thể nhận được số nhận dạng mới. Mỗi khi chúng được tạo, một R.java mới được tạo với các số nhận dạng hiện tại để mã của bạn nhận được các giá trị chính xác. Do đó, bạn không bao giờ được duy trì số nhận dạng tài nguyên ở bất kỳ nơi nào mà chúng có thể được sử dụng trên các bản dựng khác nhau của ứng dụng.

Sau khi tài nguyên được biên dịch và chỉ định số nhận dạng, aapt sẽ tạo tệp R.java cho mã nguồn của bạn và tệp nhị phân có tên "resources.arsc" chứa tất cả tên tài nguyên, số nhận dạng và giá trị (đối với tài nguyên đến từ tệp riêng biệt , giá trị của chúng là đường dẫn đến tệp đó trong .apk), ở định dạng có thể dễ dàng ánh xạ và phân tích cú pháp trên thiết bị trong thời gian chạy.

Bạn có thể nhận được bản tóm tắt của tệp resources.arsc trong apk bằng lệnh "aapt dump resources <path-to-apk>".

Định dạng của bảng tài nguyên nhị phân được ghi lại trong tệp tiêu đề cho cấu trúc dữ liệu tài nguyên ở đây:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h

Cách triển khai đầy đủ để đọc bảng tài nguyên trên thiết bị là ở đây:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/ResourceTypes.cpp


BTW, những chi tiết này có được ghi lại ở đâu đó không?
smwikipedia

Chi tiết triển khai không được ghi lại ngoài các định nghĩa cấu trúc mà tôi liên kết đến đây.
hackbod

1
BTW, IMHO, "RTFSC" là sai. Nguồn là bản giải thích về thông số kỹ thuật và có thể thay đổi. Nếu không có thông số kỹ thuật, thì hành vi chính thức là không xác định. Đọc nguồn chỉ cho bạn biết tác giả nghĩ thông số kỹ thuật có nghĩa là gì tại thời điểm họ viết nó. Nó cho bạn biết những gì xảy ra bây giờ , nhưng không phải những gì sẽ xảy ra sau này. Tuy nhiên, lời giải thích tuyệt vời của Dianne có thể sẽ cung cấp cho bạn những gì bạn cần biết và vẫn còn phù hợp cho tương lai gần.
Edward Falk

@ edward-falk: Tôi nghĩ RTFSC ở đây là chính xác vì câu hỏi đầu tiên là về những thứ bí mật (chưa bao giờ là thông số chính thức), không phải API. Spec nội bộ là SC :)
port443

Các tham chiếu đến chuỗi và các giá trị khác trong XML có được giải quyết khi xây dựng hoặc thời gian chạy không? <TextView text = "@ string / foo" />?
jophde


5

Theo những gì tôi hiểu, aapt sẽ tự động tạo các ID duy nhất cho từng tài nguyên của bạn và lưu trữ chúng trong bảng tra cứu. Bảng tra cứu này vẫn tồn tại dưới dạng tệp "resources.arsc" nằm trong "bin / resources.ap_" (đây chỉ là tệp ZIP, vì vậy hãy mở bằng trình xem ZIP yêu thích của bạn). Bảng tra cứu cũng được duy trì dưới tên R.java, như bạn đã biết cho phép bạn tham khảo các tài nguyên của mình trong Java.

Nếu bạn muốn biết thêm thông tin về tệp ARSC, tôi khuyên bạn nên sử dụng tệp ARSC hoặc xem lại mã của http://code.google.com/p/android-apktool/ .

-Dan


Cảm ơn vì manh mối quan trọng. Tôi sẽ tìm kiếm. Tôi sẽ đánh dấu câu trả lời của bạn nếu không có ai tốt hơn xuất hiện. Cảm ơn.
smwikipedia

1

Một lưu ý cuối cùng: trong thời gian dài nhất, tôi đã không sử dụng bố cục tương đối vì nhiều mục cần tham chiếu đến các mục sâu hơn trong tệp xml và tôi không biết cách tham chiếu @ id / foo chưa được xác định chưa.

<!-- doesn't work -->
<TextView android:layout_above="@id/foo">above</textview>
<TextView android:id="@+id/foo">below</textview>

Rồi một ngày tôi nhận ra (duh) rằng bạn có thể xác định một id trong tham chiếu; nó không nhất thiết phải nằm trong phần tử mang id:

<!-- works -->
<TextView android:layout_above="@+id/foo">above</textview>
<TextView android:id="@id/foo">below</textview>

0

Điều kỳ diệu nằm trong trình cắm Eclipse và tệp R.java mà nó tự động tạo trong thư mục "gen" của ứng dụng. Nếu bạn nhìn vào tệp này, bạn sẽ thấy ánh xạ tĩnh cho mọi XXX trong R.xx.XXX trong đó xx có thể là hoạt ảnh, mảng, màu và mọi loại tài nguyên khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.