Sự khác biệt giữa / res và / thư mục tài sản


266

Tôi biết rằng các tệp trong resthư mục có thể truy cập được R.classtrong khi các tài sản hoạt động giống như một hệ thống tệp, nhưng tôi muốn biết, nói chung, khi nào tốt nhất nên sử dụng cái này và cái kia.
Bất cứ ai có thể giúp tôi biết sự khác biệt thực sự giữa độ phân giải và tài sản?

Câu trả lời:


284

Với tài nguyên, có hỗ trợ tích hợp để cung cấp các lựa chọn thay thế cho các ngôn ngữ khác nhau, phiên bản HĐH, định hướng màn hình, v.v., như được mô tả ở đây . Không có cái nào có sẵn với tài sản. Ngoài ra, nhiều phần của API hỗ trợ việc sử dụng các định danh tài nguyên. Cuối cùng, tên của các tài nguyên được chuyển thành tên trường không đổi được kiểm tra tại thời điểm biên dịch, do đó, ít có cơ hội cho sự không khớp giữa mã và chính tài nguyên. Không ai trong số đó áp dụng cho tài sản.

Vậy tại sao có một thư mục tài sản? Nếu bạn muốn tính toán tài sản bạn muốn sử dụng trong thời gian chạy, điều đó khá dễ dàng. Với tài nguyên, bạn sẽ phải khai báo danh sách tất cả các ID tài nguyên có thể được sử dụng và tính toán một chỉ mục vào danh sách. (Điều này hơi khó xử và gây ra lỗi nếu bộ tài nguyên thay đổi trong chu kỳ phát triển.) (EDIT: bạn có thể truy xuất ID tài nguyên theo tên bằng cách sử dụng getIdentifier, nhưng điều này làm mất lợi ích của việc kiểm tra thời gian biên dịch.) cũng được tổ chức thành một hệ thống phân cấp thư mục, không được hỗ trợ bởi các tài nguyên. Đó là một cách khác nhau để quản lý dữ liệu. Mặc dù tài nguyên bao gồm hầu hết các trường hợp, tài sản có sử dụng không thường xuyên.

Một sự khác biệt khác: tài nguyên được xác định trong dự án thư viện được tự động nhập vào các dự án ứng dụng phụ thuộc vào thư viện. Đối với tài sản, điều đó không xảy ra; tệp tài sản phải có trong thư mục tài sản của (các) dự án ứng dụng. [EDIT: Với hệ thống xây dựng dựa trên Gradle mới của Android (được sử dụng với Android Studio), điều này không còn đúng nữa. Các thư mục tài sản cho các dự án thư viện được đóng gói vào các tệp .aar, do đó, các tài sản được xác định trong các dự án thư viện được hợp nhất vào các dự án ứng dụng (vì vậy chúng không phải có trong /assetsthư mục của ứng dụng nếu chúng nằm trong thư viện được tham chiếu).]

EDIT: Tuy nhiên, một sự khác biệt khác phát sinh nếu bạn muốn gói một phông chữ tùy chỉnh với ứng dụng của bạn. Có các lệnh gọi API để tạo một Typefacetệp từ tệp phông được lưu trữ trong hệ thống tệp hoặc trong thư mục ứng dụng của bạn assets/. Nhưng không có API để tạo một Typefacetệp từ tệp phông được lưu trong res/thư mục (hoặc từ một InputStream, cho phép sử dụng res/thư mục). [ LƯU Ý: Với Android O (hiện có sẵn trong bản xem trước alpha), bạn sẽ có thể bao gồm các phông chữ tùy chỉnh làm tài nguyên. Xem mô tả ở đây của tính năng quá hạn này. Tuy nhiên, miễn là mức API tối thiểu của bạn là 25 hoặc ít hơn, bạn sẽ phải gắn bó với việc đóng gói phông chữ tùy chỉnh dưới dạng tài sản thay vì tài nguyên.]


1
reslà viết tắt của tài nguyên, vậy thì assetsviết tắt của từ gì ??
Vivek Warde

40
@vwvwvwvwvwvwvwvwvw - Ừm ... nó không "đứng vững" bất cứ điều gì; nó đơn giản có nghĩa là "tài sản" (như ở số nhiều của tài sản từ tiếng Anh : một thứ hữu ích hoặc có giá trị ).
Ted Hopp

1
Có thể ghi vào các tập tin trong raw/thư mục?
Hoàng tử

6
@Prince - Không. Mọi thứ trong thư mục /resvà '/ nội dung' đều ở chế độ chỉ đọc, vì chúng được đóng gói trong tệp .apk.
Ted Hopp

chúng ta có thể đặt tập tin apk vào thư mục tài sản không và khi người dùng nhấp vào ui đó cài đặt apk đó?
Vivek Mishra

63

Cả hai đều khá giống nhau. Sự khác biệt chính thực sự giữa hai là trong resthư mục, mỗi tệp được biên dịch ID trước có thể dễ dàng truy cập thông qua R.id.[res id]. Điều này rất hữu ích để truy cập nhanh chóng và dễ dàng hình ảnh, âm thanh, biểu tượng ...

Thư mục assetsgiống như một hệ thống tệp và cung cấp nhiều quyền tự do hơn để đặt bất kỳ tệp nào bạn muốn vào đó. Sau đó, bạn có thể truy cập từng tệp trong hệ thống đó như khi truy cập bất kỳ tệp nào trong bất kỳ hệ thống tệp nào thông qua Java. Thư mục này tốt cho những thứ như chi tiết trò chơi, từ điển, ... vv. Mong rằng sẽ giúp.


5
Nếu chúng tôi muốn thêm default_fonts vào ứng dụng của mình thì chúng tôi sẽ đặt chúng vào thư mục tài sản.
Tushar Pandey

1
@TusharPandey Bây giờ chúng tôi không phải đặt phông chữ vào Assetsthư mục, hệ thống Android hiện có fontsthư mục và chúng tôi có thể đặt tệp phông chữ tùy chỉnh của mình ở đó hoặc chúng tôi có thể tải xuống Android studio cho chúng tôi.
CopsOnRoad

@Jack, nó dành cho Oreo.
Tushar Pandey

1
@TusharPandey Nó được thêm vào Oreo nhưng nó đã được chuyển trở lại Thư viện hỗ trợ Android trở lại cấp độ API 16.
CopsOnRoad

36

Tôi biết điều này là cũ, nhưng chỉ để làm cho nó rõ ràng, có một lời giải thích của từng trong tài liệu chính thức của Android:

từ http://developer.android.com/tools/projects/index.html

assets/

Cái này trống rỗng. Bạn có thể sử dụng nó để lưu trữ các tệp tài sản thô. Các tệp mà bạn lưu ở đây được biên dịch thành tệp .apk nguyên trạng và tên tệp gốc được giữ nguyên. Bạn có thể điều hướng thư mục này giống như một hệ thống tệp thông thường bằng cách sử dụng URI và đọc tệp dưới dạng luồng byte bằng AssetManager. Ví dụ, đây là một vị trí tốt cho kết cấu và dữ liệu trò chơi.

res/raw/

Đối với các tệp tài sản thô tùy ý. Lưu tệp tài sản ở đây thay vì trong tài sản / thư mục chỉ khác ở cách bạn truy cập chúng. Các tệp này được xử lý bởi aapt và phải được tham chiếu từ ứng dụng bằng cách sử dụng mã định danh tài nguyên trong lớp R. Ví dụ, đây là một nơi tốt cho phương tiện truyền thông, chẳng hạn như các tệp MP3 hoặc Ogg.


4
Tôi nghĩ rằng điều này thực sự gây nhầm lẫn vấn đề - cả kết cấu và tệp ogg đều là những khối dữ liệu lớn mà bạn cung cấp cho API người dùng (openGL / MediaPlayer) ... tại sao họ lại phân biệt đối xử ở đây?

9

Sau đây là một số điểm chính:

  1. Các tệp thô Phải có tên là các định danh Java hợp lệ, trong khi các tệp trong Tài sản không có giới hạn về vị trí và tên. Nói cách khác, chúng có thể được nhóm trong bất kỳ thư mục nào chúng ta muốn
  2. Các tệp thô Dễ tham khảo từ Java cũng như từ xml (tức là bạn có thể giới thiệu một tệp ở dạng thô từ tệp kê khai hoặc tệp xml khác).
  3. Lưu tệp tài sản ở đây thay vì trong tài sản / thư mục chỉ khác ở cách bạn truy cập chúng như được ghi lại ở đây http://developer.android.com/tools/projects/index.html .
  4. Các tài nguyên được xác định trong một dự án thư viện được tự động nhập vào các dự án ứng dụng phụ thuộc vào thư viện. Đối với tài sản, điều đó không xảy ra; tệp tài sản phải có trong thư mục tài sản của (các) dự án ứng dụng
  5. Thư mục tài sản giống như một hệ thống tệp cung cấp nhiều quyền tự do hơn để đặt bất kỳ tệp nào bạn muốn vào đó. Sau đó, bạn có thể truy cập từng tệp trong hệ thống đó như khi truy cập bất kỳ tệp nào trong bất kỳ hệ thống tệp nào thông qua Java. như tệp dữ liệu trò chơi, Phông chữ, kết cấu, v.v.
  6. Không giống như Tài nguyên, Tài sản có thể được tổ chức thành các thư mục con trong thư mục tài sản Tuy nhiên, điều duy nhất bạn có thể làm với một tài sản là nhận một luồng đầu vào. Do đó, sẽ không có ý nghĩa gì khi lưu trữ chuỗi hoặc bitmap của bạn trong tài sản, nhưng bạn có thể lưu trữ dữ liệu định dạng tùy chỉnh như từ điển chỉnh sửa đầu vào hoặc bản đồ trò chơi.
  7. Raw có thể cung cấp cho bạn kiểm tra thời gian biên dịch bằng cách tạo tệp R.java của bạn, tuy nhiên Nếu bạn muốn sao chép cơ sở dữ liệu của mình vào thư mục riêng, bạn có thể sử dụng Tài sản được tạo để phát trực tuyến.

Phần kết luận

  1. API Android bao gồm khung Tài nguyên rất thoải mái cũng được tối ưu hóa cho hầu hết các trường hợp sử dụng điển hình cho các ứng dụng di động khác nhau. Bạn nên nắm vững Tài nguyên và cố gắng sử dụng chúng bất cứ khi nào có thể.
  2. Tuy nhiên, nếu bạn cần linh hoạt hơn cho trường hợp đặc biệt của mình, Tài sản có sẵn để cung cấp cho bạn API cấp thấp hơn cho phép tổ chức và xử lý tài nguyên của bạn với mức độ tự do cao hơn.

Theo câu trả lời được chấp nhận, điểm 4 không còn đúng nữa, đối với các dự án sử dụng hệ thống xây dựng Gradle; tài sản từ các thư viện được gói vào bộ sưu tập tài sản của dự án ứng dụng.
Venryx

4

Nếu bạn cần giới thiệu chúng ở đâu đó trong Mã Java, bạn sẽ đưa các tệp của mình vào thư mục "res".

Và tất cả các tệp trong thư mục res sẽ được lập chỉ mục trong tệp R, giúp tải nhanh hơn (và dễ dàng hơn nhiều!).


6
Bạn cũng có thể truy cập các tệp trong tài sản từ Java
Heiko Rupp

2
Có, nhưng chúng không được lập chỉ mục -> Sẽ chậm hơn, vấn đề thực sự là gì trong phát triển di động.
L.Butz

Vì vậy, sự khác biệt giữa res / raw và tài sản là gì? Liệu res / raw cũng sẽ được lập chỉ mục?
an toàn

Kiểm tra bài đăng từ @TedHopp - Anh ấy mang đến câu trả lời thực sự rõ ràng.
L.Butz

1

Sử dụng các tài sản như một hệ thống tệp để kết xuất bất kỳ loại tệp nào. Và sử dụng res để lưu trữ những gì nó được tạo ra, bố cục, hình ảnh, giá trị.


0

Ted Hopp đã trả lời điều này khá độc đáo. Tôi đã sử dụng res / raw cho các tập tin shader và texture của tôi. Tôi đã suy nghĩ về việc chuyển chúng vào một thư mục tài sản để cung cấp một tổ chức phân cấp.

Chủ đề này đã thuyết phục tôi không. Đầu tiên, vì tôi thích việc sử dụng id tài nguyên duy nhất. Thứ hai bởi vì nó rất đơn giản để sử dụng InputStream / openRawResource hoặc BitmapFactory để đọc trong tệp. Thứ ba bởi vì nó rất hữu ích để có thể sử dụng trong thư viện di động.


1
Điểm 2, hỗ trợ InputStreams và BitmapFactory, đúng cho cả tài nguyên và tài sản (xem tại đây: stackoverflow.com/a/8501428/2441655 ). Điểm 3 không còn áp dụng. (xem câu trả lời được chấp nhận)
Venryx

-5

Tài sản cung cấp một cách để bao gồm các tệp tùy ý như văn bản, xml, phông chữ, nhạc và video trong ứng dụng của bạn. Nếu bạn cố gắng đưa các tệp này làm "tài nguyên", Android sẽ xử lý chúng vào hệ thống tài nguyên của nó và bạn sẽ không thể lấy dữ liệu thô. Nếu bạn muốn truy cập dữ liệu chưa được xử lý, Tài sản là một cách để làm điều đó.


5
Điều này là không đúng. Nếu bạn đặt dữ liệu vào res/raw, bạn có thể lấy dữ liệu thô bằng cách sử dụng openRawResource(resourceName).
Ted Hopp

Tôi có các tập tin kết cấu và shader trong thư viện. Tôi PHẢI sử dụng res / raw để lưu trữ chúng. Tôi sử dụng InputStream và BitmapFactory để đọc chúng. Tôi sẽ thêm điều này như một bình luận độc lập.
dturvene

Có vẻ được sao chép từ tài liệu Xamarin Microsoft. Cung cấp nguồn của bạn khi sao chép văn bản. docs.microsoft.com/en-us/xamarin/android/app-fundamentals/ Khăn
Sjoerd Pottuit
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.