Tài nguyên là các tệp bổ sung và nội dung tĩnh mà mã của bạn sử dụng, chẳng hạn như bitmap, chuỗi giao diện người dùng, hướng dẫn về ảnh động, v.v.
Hãy luôn tách riêng các tài nguyên ứng dụng (chẳng hạn như hình ảnh và chuỗi) khỏi đoạn mã để có thể duy trì chúng một cách độc lập. Ngoài ra, hãy cung cấp tài nguyên thay thế cho các cấu hình thiết bị cụ thể bằng cách nhóm những tài nguyên đó trong các thư mục tài nguyên có tên riêng. Trong thời gian chạy, Android sử dụng tài nguyên phù hợp dựa trên cấu hình hiện tại. Ví dụ: bạn nên cung cấp các chuỗi khác nhau, tuỳ thuộc vào chế độ cài đặt ngôn ngữ.
Sau khi tách tài nguyên ứng dụng, bạn có thể truy cập vào các tài nguyên này bằng cách sử dụng mã nhận dạng tài nguyên được tạo trong lớp R của dự án.
Tài liệu này cho bạn biết cách nhóm các tài nguyên trong dự án Android. Tài liệu này cũng chỉ cho bạn cách cung cấp tài nguyên thay thế cho cấu hình thiết bị cụ thể, sau đó truy cập vào những tài nguyên đó từ đoạn mã ứng dụng hoặc các tệp XML khác.
Nhóm các loại tài nguyên
Đặt mỗi loại tài nguyên vào một thư mục con cụ thể thuộc thư mục res/ của dự án. Ví dụ: sau đây là hệ phân cấp tệp của một dự án đơn giản:
MyProject/
src/
MyActivity.kt
res/
drawable/
graphic.png
mipmap/
icon.png
values/
strings.xml
Thư mục res/ chứa mọi tài nguyên trong các thư mục con: 1 tài nguyên hình ảnh, 1 thư mục mipmap/ cho các biểu tượng trình chạy và 1 tệp tài nguyên chuỗi. Tên thư mục tài nguyên rất quan trọng và được mô tả trong Bảng 1.
Lưu ý: Để biết thêm thông tin về cách sử dụng thư mục mipmap, hãy xem phần Đặt biểu tượng ứng dụng trong thư mục mipmap.
Bảng 1. Các thư mục tài nguyên được hỗ trợ bên trong thư mục res/ của dự án.
| Thư mục | Loại tài nguyên |
|---|---|
drawable/ |
Tệp bitmap (PNG,
Để biết thêm thông tin, hãy xem bài viết Tài nguyên có thể vẽ. |
mipmap/ |
Các tệp có thể vẽ cho những mật độ biểu tượng trình chạy khác nhau. Để biết thêm thông tin về cách quản lý biểu tượng trình chạy bằng các thư mục mipmap/, vui lòng xem phần Đặt biểu tượng ứng dụng trong thư mục mipmap. |
raw/ |
Các tệp tuỳ ý để lưu ở dạng thô của các tệp này. Để mở các tài nguyên này bằng Tuy nhiên, nếu bạn cần quyền truy cập vào tên tệp gốc và hệ phân cấp tệp, hãy cân nhắc việc lưu tài nguyên trong thư mục |
values/ |
Tệp XML chứa các giá trị đơn giản, chẳng hạn như chuỗi, số nguyên và màu. Trong khi các tệp tài nguyên XML ở các thư mục con Vì mỗi tài nguyên được xác định bằng phần tử XML riêng, nên bạn có thể tuỳ ý đặt tên cho tệp và đặt nhiều loại tài nguyên trong một tệp. Tuy nhiên, để cho rõ ràng, bạn nên đặt những loại tài nguyên duy nhất trong các tệp khác nhau. Ví dụ: sau đây là một số quy ước về tên tệp cho những tài nguyên mà bạn có thể tạo trong thư mục này:
Để biết thêm thông tin, hãy xem bài viết Tài nguyên chuỗi, Tài nguyên kiểu và Các loại tài nguyên khác. |
xml/ |
Các tệp XML tuỳ ý có thể được đọc trong thời gian chạy bằng cách gọi Resources.getXML. Bạn phải lưu các tệp cấu hình XML khác nhau vào đây.
|
font/ |
Các tệp phông chữ có đuôi như TTF, OTF hoặc TTC, hoặc các tệp XML có chứa phần tử <font-family>. Để biết thêm thông tin về phông chữ ở dạng tài nguyên, hãy xem bài viết Thêm phông chữ ở dạng tài nguyên XML.
|
Thận trọng: Đừng bao giờ lưu tệp tài nguyên ngay trong thư mục res/ vì việc này sẽ gây ra lỗi trình biên dịch.
Tài nguyên mà bạn lưu trong các thư mục con được xác định trong Bảng 1 là tài nguyên mặc định. Tức là những tài nguyên này xác định thiết kế và nội dung mặc định cho ứng dụng của bạn. Tuy nhiên, mỗi loại thiết bị chạy Android có thể yêu cầu các loại tài nguyên khác nhau.
Ví dụ: bạn có thể cung cấp nhiều tài nguyên chuỗi để dịch văn bản trong giao diện người dùng dựa trên chế độ cài đặt ngôn ngữ của thiết bị.
Lưu ý: Trong Compose, giao diện người dùng, ảnh động và màu sắc dựa trên trạng thái được khai báo trong Kotlin, vì vậy, các thư mục layout/, menu/, anim/, animator/ và color/ không còn được dùng cho các ứng dụng hiện đại. Để biết thêm thông tin, hãy xem phần Ảnh động trong Compose và Kết cấu của một giao diện trong Compose.
Cung cấp tài nguyên thay thế
Hầu hết ứng dụng đều cung cấp tài nguyên thay thế để hỗ trợ các cấu hình thiết bị cụ thể. Ví dụ: thêm các tài nguyên có thể vẽ thay thế cho nhiều mật độ màn hình và tài nguyên chuỗi thay thế cho nhiều ngôn ngữ. Trong thời gian chạy, Android sẽ phát hiện cấu hình thiết bị hiện tại và tải các tài nguyên thích hợp cho ứng dụng của bạn.
Để chỉ định các tài nguyên thay thế theo cấu hình cụ thể cho một nhóm tài nguyên, hãy làm như sau:
- Tạo một thư mục mới trong
res/có tên trong biểu mẫu<resources_name>-<qualifier>.<resources_name>là tên thư mục của các tài nguyên mặc định tương ứng (được xác định trong Bảng 1).<qualifier>là tên chỉ định một cấu hình riêng lẻ để sử dụng những tài nguyên này (được xác định trong Bảng 2).
Bạn có thể thêm nhiều
<qualifier>. Phân tách từng mã bằng dấu gạch ngang.Chú ý: Khi thêm nhiều bộ hạn định, bạn phải đặt các bộ hạn định đó theo thứ tự được liệt kê trong Bảng 2. Nếu bạn sắp xếp các bộ hạn định không chính xác, thì các tài nguyên sẽ bị bỏ qua.
- Lưu các tài nguyên thay thế thích hợp trong thư mục mới này. Các tệp tài nguyên phải được đặt tên giống hệt với tệp tài nguyên mặc định.
Ví dụ: dưới đây là một số tài nguyên mặc định và tài nguyên thay thế:
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
Bộ hạn định hdpi cho biết các tài nguyên trong thư mục đó dành cho các thiết bị có màn hình với độ phân giải cao. Hình ảnh trong các thư mục có thể vẽ này được định kích thước cho mật độ màn hình cụ thể, nhưng tên tệp thì giống hệt nhau. Bằng cách này, mã nhận dạng tài nguyên mà bạn dùng để tham chiếu hình ảnh icon.png hoặc background.png luôn giống nhau. Android chọn phiên bản của từng tài nguyên phù hợp nhất với thiết bị hiện tại bằng cách so sánh thông tin cấu hình thiết bị với bộ hạn định trong tên thư mục tài nguyên.
Thận trọng: Khi xác định tài nguyên thay thế, hãy đảm bảo bạn cũng xác định tài nguyên trong cấu hình mặc định. Nếu không, ứng dụng của bạn có thể gặp phải trường hợp ngoại lệ về thời gian chạy khi thiết bị thay đổi cấu hình. Ví dụ: nếu bạn chỉ thêm một chuỗi vào values-en chứ không phải values, ứng dụng của bạn có thể gặp phải trường hợp ngoại lệ Resource Not Found khi người dùng thay đổi ngôn ngữ hệ thống mặc định.
Bảng 2 liệt kê các bộ hạn định cấu hình theo thứ tự ưu tiên. Bạn có thể thêm nhiều bộ hạn định vào một tên thư mục bằng cách dùng dấu gạch ngang phân tách từng bộ hạn định. Nếu sử dụng nhiều bộ hạn định cho một thư mục tài nguyên, bạn phải thêm các bộ hạn định đó vào tên thư mục theo thứ tự liệt kê trong bảng.
Bảng 2. Tên bộ hạn định cấu hình.
| Cấu hình | Giá trị bộ hạn định | Nội dung mô tả |
|---|---|---|
| MCC và MNC | Ví dụ:mcc310mcc208-mnc00
|
Mã di động quốc gia (MCC), theo sau là mã mạng di động (MNC) (không bắt buộc) có trên thẻ SIM trong thiết bị. Ví dụ: Nếu thiết bị sử dụng kết nối vô tuyến (tức là điện thoại GSM), thì giá trị MCC và MNC sẽ có trên thẻ SIM. Bạn cũng có thể sử dụng riêng MCC, ví dụ: để đưa các tài nguyên pháp lý ở từng quốc gia vào ứng dụng của bạn. Nếu bạn chỉ cần chỉ định dựa trên ngôn ngữ, hãy dùng bộ hạn định ngôn ngữ, tập lệnh (không bắt buộc) và khu vực (không bắt buộc). Nếu bạn dùng bộ hạn định MCC và MNC, hãy cẩn thận khi làm vậy và kiểm thử để chắc chắn chúng hoạt động như dự kiến. Ngoài ra, hãy xem các trường cấu hình |
| Ngôn ngữ, tập lệnh (không bắt buộc) và khu vực (không bắt buộc) | Ví dụ:enfren-rUSfr-rFRfr-rCAb+enb+en+USb+es+419b+zh+Hantb+sr+Latn+RS |
Ngôn ngữ này được xác định bằng mã ngôn ngữ gồm 2 chữ cái theo tiêu chuẩn ISO 639-1, có thể theo sau là mã vùng gồm 2 chữ cái theo tiêu chuẩn ISO 3166-1-alpha-2 (đứng trước Các mã này không phân biệt chữ hoa chữ thường. Tiền tố Android 7.0 (API cấp 24) đã ra mắt tính năng hỗ trợ thẻ ngôn ngữ BCP 47. Bạn có thể dùng các thẻ này để đáp ứng điều kiện về tài nguyên dành riêng cho từng ngôn ngữ và khu vực. Thẻ ngôn ngữ được tạo từ một trình tự gồm một hoặc nhiều thẻ phụ, mỗi thẻ trong số đó sẽ tinh chỉnh hoặc thu hẹp phạm vi ngôn ngữ mà thẻ tổng thể xác định. Để biết thêm thông tin về thẻ ngôn ngữ, hãy xem phần Thẻ để xác định ngôn ngữ. Để sử dụng thẻ ngôn ngữ BCP 47, hãy nối Thẻ ngôn ngữ có thể thay đổi trong suốt thời gian hoạt động của ứng dụng nếu người dùng thay đổi ngôn ngữ trong phần cài đặt hệ thống. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình. Để xem hướng dẫn đầy đủ về cách bản địa hoá ứng dụng cho các ngôn ngữ khác, hãy xem bài viết Bản địa hoá ứng dụng. Ngoài ra, hãy xem phương thức |
| Giống trong ngữ pháp | masculinefeminineneuter |
Giống trong ngữ pháp của người dùng. Được dùng cho những ngôn ngữ có giống trong ngữ pháp. Ví dụ: nếu cần cung cấp các tài nguyên khác nhau cho người dùng nói tiếng Pháp, thì bạn có thể sử dụng các thư mục như sau:
Xem phần Dùng yếu tố giống trong ngữ pháp để cá nhân hoá giao diện người dùng của ứng dụng. Ngoài ra, hãy xem phương thức cấu hình Đã thêm vào cấp độ API 34. |
| Gam màu rộng |
widecgnowidecg
|
Đã thêm vào API cấp 26. Ngoài ra, hãy xem phương thức cấu hình |
| Dải động cao (HDR) |
highdrlowdr
|
Đã thêm vào API cấp 26. Ngoài ra, hãy xem phương thức cấu hình |
| Chế độ giao diện người dùng |
cardesktelevisionappliancewatchvrheadset
|
Đã thêm vào cấp độ API 8; TV được thêm vào API 13; thiết bị gia dụng được thêm vào API 16; đồng hồ được thêm vào API 20; vrheadset được thêm vào API 26. Để biết thông tin về cách ứng dụng của bạn có thể phản hồi khi thiết bị được cắm vào hoặc bị tháo khỏi đế, hãy đọc bài viết Xác định và theo dõi trạng thái cũng như loại đế sạc. Các chế độ này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu người dùng đặt thiết bị vào một đế. Bạn có thể bật hoặc tắt một số chế độ này bằng |
| Chế độ ban đêm |
nightnotnight
|
Đã thêm vào API cấp 8. Điều này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu bạn để chế độ ban đêm ở chế độ tự động (mặc định). Trong trường hợp này, chế độ này thay đổi dựa vào thời gian trong ngày. Bạn có thể bật hoặc tắt chế độ này bằng |
| Mật độ pixel màn hình (dpi) |
ldpimdpihdpixhdpixxhdpixxxhdpinodpitvdpianydpinnndpi
|
Có một tỷ lệ xích là 3:4:6:8:12:16 giữa 6 mật độ chính (bỏ qua mật độ tvdpi). Vì vậy, một bitmap 9x9 ở ldpi là 12x12 ở mdpi, 18x18 ở hdpi, 24x24 ở xhdpi, v.v. Lưu ý: Việc sử dụng bộ hạn định mật độ không có nghĩa là tài nguyên chỉ dành cho màn hình có mật độ đó. Nếu bạn không cung cấp tài nguyên thay thế có bộ hạn định phù hợp hơn với cấu hình thiết bị hiện tại, thì hệ thống có thể sử dụng bất kỳ tài nguyên nào phù hợp nhất. Để biết thêm thông tin về cách xử lý các mật độ màn hình khác nhau và cách Android có thể điều chỉnh bitmap theo tỷ lệ cho phù hợp với mật độ hiện tại, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình. |
| Loại màn hình cảm ứng |
notouchfinger
|
Ngoài ra, hãy xem trường cấu hình |
| Khả năng sử dụng bàn phím |
keysexposedkeyshiddenkeyssoft
|
Nếu bạn cung cấp tài nguyên Điều này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu người dùng mở bàn phím phần cứng. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình. Ngoài ra, hãy xem các trường cấu hình |
| Phương thức nhập văn bản chính |
nokeysqwerty12key
|
Ngoài ra, hãy xem trường cấu hình |
| Khả năng sử dụng phím điều hướng |
navexposednavhidden
|
Điều này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu người dùng cho thấy các phím điều hướng. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình. Ngoài ra, hãy xem trường cấu hình |
| Phương thức điều hướng chính không chạm |
nonavdpadtrackballwheel
|
Ngoài ra, hãy xem trường cấu hình |
| Phiên bản nền tảng (cấp độ API) | Ví dụ:v3v4v7, v.v. |
Cấp độ API mà thiết bị hỗ trợ. Ví dụ: |
Lưu ý: Không phải phiên bản Android nào cũng hỗ trợ mọi bộ hạn định. Việc sử dụng bộ hạn định mới sẽ ngầm thêm bộ hạn định phiên bản nền tảng để các thiết bị cũ có thể bỏ qua bộ hạn định đó. Để tránh mọi sự cố, hãy luôn thêm một nhóm tài nguyên mặc định (một nhóm tài nguyên không có bộ hạn định). Để biết thêm thông tin, hãy xem phần cung cấp khả năng tương thích tốt nhất với thiết bị bằng tài nguyên.
Trong các ứng dụng Compose, bạn không cần đến các bộ đủ tiêu chuẩn về cấu hình liên quan đến bố cục và kích thước. Mặc dù vẫn tồn tại, nhưng các mục này sẽ bị loại trừ khỏi Bảng 2. Các bộ hạn định này bao gồm: hướng bố cục, chiều rộng nhỏ nhất, chiều rộng có sẵn, chiều cao có sẵn, kích thước màn hình, tỷ lệ khung hình màn hình, màn hình tròn và hướng màn hình. Để xem toàn bộ bảng bộ hạn định cấu hình theo thứ tự ưu tiên, hãy xem phần Tổng quan về tài nguyên ứng dụng (Chế độ xem).
Quy tắc về tên bộ hạn định
Dưới đây là một số quy tắc về việc sử dụng tên bộ hạn định cấu hình:
- Bạn có thể chỉ định nhiều bộ hạn định cho một nhóm tài nguyên, phân tách bằng dấu gạch ngang. Ví dụ:
drawable-en-rUS-nightáp dụng cho các thiết bị Tiếng Anh-Mỹ ở chế độ ban đêm. - Bộ hạn định phải theo thứ tự được liệt kê trong Bảng 2.
- Sai:
drawable-hdpi-night/ - Đúng:
drawable-night-hdpi/
- Sai:
- Không thể lồng các thư mục tài nguyên thay thế. Ví dụ: bạn không thể có
res/drawable/drawable-en/. - Các giá trị không phân biệt chữ hoa chữ thường. Trình biên dịch tài nguyên chuyển đổi tên thư mục thành chữ thường trước khi xử lý để tránh các sự cố trên hệ thống tệp không phân biệt chữ hoa chữ thường. Mọi cách viết hoa trong tên chỉ mang lại lợi ích dễ đọc.
- Chỉ hỗ trợ một giá trị cho mỗi loại bộ hạn định. Ví dụ: nếu muốn sử dụng cùng một tệp có thể vẽ cho Tây Ban Nha và Pháp, bạn không thể tạo thư mục có tên là
drawable-es-fr/. Thay vào đó, bạn cần có 2 thư mục tài nguyên, chẳng hạn nhưdrawable-es/vàdrawable-fr/chứa các tệp thích hợp.
Sau khi bạn lưu tài nguyên thay thế vào các thư mục được đặt tên bằng bộ hạn định này, Android sẽ tự động áp dụng các tài nguyên trong ứng dụng của bạn dựa trên cấu hình hiện tại của thiết bị. Mỗi khi có tài nguyên được yêu cầu, Android sẽ kiểm tra các thư mục tài nguyên thay thế xem có chứa tệp tài nguyên được yêu cầu hay không, sau đó tìm tài nguyên phù hợp nhất.
Nếu không có tài nguyên thay thế nào phù hợp với một cấu hình thiết bị cụ thể, thì Android sẽ sử dụng các tài nguyên mặc định tương ứng – nhóm tài nguyên cho một loại tài nguyên cụ thể không bao gồm bộ hạn định cấu hình.
Tạo tài nguyên đại diện
Khi có một tài nguyên mà bạn muốn sử dụng cho nhiều cấu hình thiết bị nhưng không muốn cung cấp ở dạng tài nguyên mặc định, bạn không cần phải đặt cùng một tài nguyên vào nhiều thư mục tài nguyên thay thế. Thay vào đó, bạn có thể tạo một tài nguyên thay thế đóng vai trò là đại diện cho một tài nguyên được lưu trong thư mục tài nguyên mặc định của bạn.
Đối tượng có thể vẽ
Ví dụ: giả sử bạn có biểu tượng ứng dụng icon.png và cần một phiên bản độc đáo cho các ngôn ngữ khác nhau. Tuy nhiên, 2 ngôn ngữ là Tiếng Anh-Canada và Tiếng Pháp-Canada cần sử dụng cùng một phiên bản. Bạn không cần sao chép cùng một hình ảnh vào thư mục tài nguyên cho cả tiếng Anh-Canada và tiếng Pháp-Canada.
Thay vào đó, bạn có thể lưu hình ảnh dùng cho cả hai với bất kỳ tên nào không phải icon.png, chẳng hạn như icon_ca.png rồi đặt hình ảnh đó vào thư mục res/drawable/ mặc định. Sau đó, hãy tạo một tệp icon.xml trong res/drawable-en-rCA/ và res/drawable-fr-rCA/ tham chiếu đến tài nguyên icon_ca.png bằng cách sử dụng phần tử <bitmap>.
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/icon_ca" />
Việc này cho phép bạn chỉ lưu trữ 1 phiên bản của tệp PNG và 2 tệp XML nhỏ trỏ đến tệp đó.
Sau đó, bạn có thể sử dụng painterResource(R.drawable.icon) và hệ thống sẽ chọn tệp thích hợp sau khi phát hiện ngôn ngữ.
Chuỗi và các giá trị đơn giản khác
Để tạo một đại diện cho một chuỗi hiện có, hãy sử dụng mã nhận dạng tài nguyên của chuỗi mong muốn làm giá trị cho chuỗi mới:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello</string> <string name="hi">@string/hello</string> </resources>
Tài nguyên R.string.hi hiện là đại diện của R.string.hello.
Các giá trị đơn giản khác cũng hoạt động theo cách tương tự, chẳng hạn như màu:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red">#f00</color> <color name="highlight">@color/red</color> </resources>
Truy cập vào tài nguyên ứng dụng của bạn
Sau khi cung cấp tài nguyên trong ứng dụng, bạn có thể áp dụng tài nguyên đó bằng cách tham chiếu mã nhận dạng tài nguyên của tài nguyên đó. Mọi mã nhận dạng tài nguyên đều được xác định trong lớp R của dự án mà công cụ aapt sẽ tự động tạo.
Khi ứng dụng của bạn được biên dịch, aapt sẽ tạo lớp R, chứa mã nhận dạng tài nguyên cho mọi tài nguyên trong thư mục res/. Đối với mỗi loại tài nguyên, có một lớp con R, chẳng hạn như R.drawable cho mọi tài nguyên có thể vẽ. Mỗi tài nguyên thuộc loại đó đều có một số nguyên tĩnh, ví dụ: R.drawable.icon. Số nguyên này là mã nhận dạng tài nguyên mà bạn có thể dùng để truy xuất tài nguyên của mình.
Mặc dù lớp R là nơi có mã nhận dạng tài nguyên được chỉ định, nhưng bạn không cần phải tìm đến đó để khám phá mã nhận dạng tài nguyên. Mã nhận dạng tài nguyên luôn bao gồm các thành phần sau:
- Loại tài nguyên: mỗi tài nguyên được nhóm thành một "loại", chẳng hạn như
stringhoặcdrawable. - Tên tài nguyên là tên tệp, không bao gồm đuôi tệp.
Truy cập vào tài nguyên trong Compose
Jetpack Compose cung cấp các hàm tích hợp, có khả năng kết hợp để truy cập vào tài nguyên một cách an toàn.
- Chuỗi:
stringResource(id = R.string.hello)
- Drawable:
painterResource(id = R.drawable.my_icon)
Truy cập vào tài nguyên trong mã không phải giao diện người dùng
Nếu cần truy cập vào các tài nguyên bên ngoài hệ phân cấp giao diện người dùng (chẳng hạn như trong ViewModel, Repository hoặc Service hệ thống), bạn có thể phân giải các tài nguyên đó bằng Context.
// Retrieve a localized string resource val greeting = context.getString(R.string.hello_world)
Bạn cũng có thể truy xuất từng tài nguyên riêng lẻ bằng các phương thức trong Resources. Bạn có thể lấy thực thể này của getResources.
Cú pháp
Dưới đây là cú pháp để tham chiếu một tài nguyên trong mã:
[<package_name>.]R.<resource_type>.<resource_name>
<package_name>là tên của gói chứa tài nguyên (không bắt buộc khi tham chiếu tài nguyên từ gói của bạn).<resource_type>là lớp conRcho loại tài nguyên.<resource_name>là tên tệp tài nguyên không có đuôi hoặc giá trị thuộc tínhandroid:nametrong phần tử XML, đối với các giá trị đơn giản.
Để biết thêm thông tin về từng loại tài nguyên và cách tham chiếu, hãy xem bài viết Tài nguyên trong Compose.
Truy cập vào tệp gốc
Mặc dù không phổ biến, nhưng bạn có thể cần phải truy cập vào các tệp và thư mục gốc. Nếu truy cập vào thì bạn sẽ không thể lưu tệp trong res/, vì cách duy nhất để đọc tài nguyên từ res/ là dùng mã nhận dạng tài nguyên. Thay vào đó, bạn có thể lưu tài nguyên trong thư mục assets/.
Các tệp đã lưu trong thư mục assets/ không được cấp mã nhận dạng tài nguyên. Do đó, bạn không thể tham chiếu đến các tệp này thông qua lớp R hoặc từ tài nguyên XML. Thay vào đó, bạn có thể truy vấn các tệp trong thư mục assets/ như một hệ thống tệp thông thường và đọc dữ liệu thô bằng cách sử dụng AssetManager.
Tuy nhiên, nếu bạn chỉ cần đọc dữ liệu thô (chẳng hạn như tệp video hoặc tệp âm thanh), thì hãy lưu tệp đó vào thư mục res/raw/ và đọc một luồng byte bằng openRawResource.
Truy cập vào tài nguyên của nền tảng
Android chứa một số tài nguyên chuẩn, chẳng hạn như kiểu và giao diện hệ thống. Để truy cập vào các tài nguyên này, hãy xác định điều kiện tham chiếu tài nguyên bằng lớp gói android. Ví dụ:
painterResource(android.R.drawable.ic_menu_info_details).
Cung cấp khả năng tương thích tốt nhất với thiết bị bằng các tài nguyên
Để ứng dụng của bạn hỗ trợ nhiều cấu hình thiết bị, bạn phải luôn cung cấp tài nguyên mặc định cho mỗi loại tài nguyên mà ứng dụng của bạn dùng.
Ví dụ: nếu ứng dụng của bạn hỗ trợ nhiều ngôn ngữ, hãy luôn thêm thư mục values/ (nơi các chuỗi được lưu) không có bộ hạn định ngôn ngữ và khu vực. Thay vào đó, nếu bạn đặt mọi tệp chuỗi của mình vào thư mục có bộ hạn định ngôn ngữ và khu vực, thì ứng dụng sẽ gặp sự cố khi chạy trên thiết bị được đặt thành ngôn ngữ mà các chuỗi đó không hỗ trợ.
Miễn là bạn cung cấp tài nguyên values/ mặc định, thì ứng dụng sẽ chạy đúng cách, ngay cả khi người dùng không hiểu ngôn ngữ được hiển thị. Dù sao thì vẫn tốt hơn là gặp sự cố.
Việc cung cấp tài nguyên mặc định không chỉ quan trọng vì ứng dụng của bạn có thể chạy trên một cấu hình ngoài dự kiến, mà còn vì các phiên bản Android mới đôi khi sẽ thêm những bộ hạn định cấu hình mà các phiên bản thấp hơn không hỗ trợ. Nếu bạn sử dụng một bộ hạn định tài nguyên mới, nhưng vẫn duy trì khả năng tương thích mã với các phiên bản Android thấp hơn, thì khi một phiên bản Android thấp hơn chạy ứng dụng của bạn, ứng dụng đó sẽ gặp sự cố nếu bạn không cung cấp tài nguyên mặc định, vì ứng dụng không thể sử dụng tài nguyên có tên bộ hạn định mới.
Ví dụ: nếu minSdkVersion của bạn được đặt thành 4 và bạn đủ điều kiện dùng mọi tài nguyên có thể vẽ của mình bằng cách sử dụng chế độ ban đêm (night hoặc notnight đã được thêm vào API cấp 8), thì thiết bị API cấp 4 không thể truy cập vào các tài nguyên có thể vẽ của bạn và sẽ gặp sự cố. Trong trường hợp này, bạn có thể muốn notnight trở thành tài nguyên mặc định. Vì vậy, bạn nên loại trừ bộ hạn định đó để các tài nguyên có thể vẽ sẽ ở dạng drawable/ hoặc drawable-night/.
Tóm lại, để cung cấp khả năng tương thích tốt nhất với thiết bị, hãy luôn cung cấp tài nguyên mặc định cho các tài nguyên mà ứng dụng của bạn cần để có thể hoạt động đúng cách. Sau đó, hãy tạo tài nguyên thay thế cho các cấu hình thiết bị cụ thể bằng cách sử dụng bộ hạn định cấu hình.
Có một ngoại lệ đối với quy tắc này: Nếu minSdkVersion của ứng dụng là 4 trở lên, bạn không cần tài nguyên có thể vẽ mặc định khi cung cấp tài nguyên có thể vẽ thay thế với bộ hạn định mật độ màn hình. Ngay cả khi không có tài nguyên có thể vẽ mặc định, Android vẫn có thể tìm thấy kết quả phù hợp nhất trong số các mật độ màn hình thay thế và điều chỉnh bitmap theo tỷ lệ nếu cần. Tuy nhiên, để có trải nghiệm tốt nhất trên mọi loại thiết bị, hãy cung cấp các tài nguyên có thể vẽ thay thế cho cả 3 loại mật độ.
Cách Android tìm ra tài nguyên phù hợp nhất
Khi bạn yêu cầu một tài nguyên mà bạn cung cấp các tài nguyên thay thế, Android sẽ dựa vào cấu hình thiết bị hiện tại để chọn tài nguyên thay thế nhằm sử dụng trong thời gian chạy. Để minh hoạ cách Android chọn một tài nguyên thay thế, hãy giả sử mỗi thư mục có thể vẽ sau đây chứa các phiên bản khác nhau của cùng hình ảnh:
drawable/ drawable-en/ drawable-fr-rCA/ drawable-en-night/ drawable-en-notouch-12key/ drawable-night-ldpi/ drawable-night-notouch-12key/
Đồng thời giả sử sau đây là cấu hình thiết bị:
Ngôn ngữ = en-GB
Chế độ ban đêm = night
Mật độ pixel màn hình = hdpi
Loại màn hình cảm ứng = notouch
Phương thức nhập văn bản chính = 12key
Bằng cách so sánh cấu hình thiết bị với tài nguyên thay thế có sẵn, Android sẽ chọn các đối tượng có thể vẽ từ drawable-en-night.
Hệ thống đưa ra quyết định về tài nguyên sẽ sử dụng với logic sau:
Hình 2. Sơ đồ quy trình về cách Android tìm được tài nguyên phù hợp nhất.
- Loại bỏ những tệp tài nguyên xung đột với cấu hình thiết bị.
Thư mục
drawable-fr-rCA/bị loại bỏ vì thư mục này xung đột với ngôn ngữen-GB.drawable/ drawable-en/
drawable-fr-rCA/drawable-en-night/ drawable-en-notouch-12key/ drawable-night-ldpi/ drawable-night-notouch-12key/Ngoại lệ: Mật độ pixel trên màn hình là một bộ hạn định không bị loại bỏ do xung đột. Mặc dù mật độ màn hình của thiết bị là hdpi, nhưng
drawable-night-ldpi/sẽ không bị loại bỏ vì mọi mật độ màn hình đều được coi là khớp tại thời điểm này. Để biết thông tin, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình. - Tìm bộ hạn định có mức độ ưu tiên cao nhất tiếp theo trong danh sách (Bảng 2). (Bắt đầu bằng MCC.)
- Có thư mục tài nguyên nào bao gồm bộ hạn định này không?
- Nếu không, hãy quay lại bước 2 và xem bộ hạn định tiếp theo. Trong ví dụ này, câu trả lời là "không" cho đến khi câu trả lời là bộ hạn định ngôn ngữ.
- Nếu có, hãy chuyển sang bước 4.
- Loại bỏ các thư mục tài nguyên không bao gồm bộ hạn định này. Trong ví dụ này, tiếp theo, hệ thống sẽ loại bỏ tất cả các thư mục không bao gồm bộ hạn định ngôn ngữ:
drawable/drawable-en/ drawable-en-night/ drawable-en-notouch-12key/drawable-night-ldpi/drawable-night-notouch-12key/Ngoại lệ: Nếu bộ hạn định được đề cập trong câu hỏi là mật độ pixel trên màn hình, thì Android sẽ chọn lựa chọn phù hợp nhất với mật độ màn hình của thiết bị. Nhìn chung, Android muốn giảm kích thước hình ảnh gốc lớn hơn để mở rộng hình ảnh gốc nhỏ hơn. Để biết thêm thông tin, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình.
- Lặp lại các bước 2, 3 và 4 cho đến khi chỉ còn một thư mục. Trong ví dụ này, chế độ ban đêm là bộ hạn định tiếp theo mà sẽ có bất kỳ kết quả trùng khớp nào.
Do đó, những tài nguyên không chỉ định chế độ ban đêm sẽ bị loại bỏ:
drawable-en/drawable-en-night/drawable-en-notouch-12key/Thư mục còn lại là
drawable-en-night.
Mặc dù quy trình này được thực thi cho mỗi tài nguyên được yêu cầu, nhưng hệ thống sẽ tối ưu hoá một số khía cạnh của quy trình. Một trong những cách tối ưu hoá này là khi đã biết cấu hình của thiết bị, hệ thống có thể loại bỏ các tài nguyên thay thế không bao giờ khớp. Ví dụ: nếu ngôn ngữ cấu hình là tiếng Anh, thì mọi thư mục tài nguyên có bộ hạn định ngôn ngữ được đặt thành một ngôn ngữ khác tiếng Anh sẽ không bao giờ được đưa vào nhóm tài nguyên được đánh dấu (mặc dù thư mục tài nguyên không có bộ hạn định ngôn ngữ vẫn được bao gồm).
Khi chọn tài nguyên dựa trên bộ hạn định kích thước màn hình, hệ thống sẽ sử dụng tài nguyên được thiết kế cho một màn hình nhỏ hơn màn hình hiện tại nếu không có tài nguyên nào phù hợp hơn. Ví dụ: màn hình kích thước lớn sẽ sử dụng tài nguyên màn hình kích thước bình thường nếu cần.
Tuy nhiên, nếu tài nguyên duy nhất hiện có lớn hơn màn hình hiện tại, thì hệ thống sẽ không sử dụng các tài nguyên đó và ứng dụng của bạn sẽ gặp sự cố nếu không có tài nguyên nào khác khớp với cấu hình thiết bị. Ví dụ: sự cố này xảy ra nếu tất cả tài nguyên bố cục được gắn thẻ với bộ hạn định xlarge, nhưng thiết bị là màn hình có kích thước bình thường.
Lưu ý: Mức độ ưu tiên của bộ hạn định (trong Bảng 2) quan trọng hơn số lượng bộ hạn định khớp chính xác với thiết bị. Trong ví dụ trước, ở bước 4, lựa chọn cuối cùng trong danh sách có 3 bộ hạn định khớp chính xác với thiết bị (chế độ ban đêm, loại màn hình cảm ứng và phương thức nhập), trong khi drawable-en chỉ có một tham số phù hợp (ngôn ngữ). Tuy nhiên, ngôn ngữ có mức độ ưu tiên cao hơn so với các bộ hạn định này, vì vậy drawable-night-notouch-12key sẽ bị loại bỏ.
Tài nguyên khác
Để tìm hiểu thêm về tài nguyên ứng dụng, hãy xem thêm các tài nguyên sau: