ความแตกต่างระหว่างไดเร็กทอรี / res และ / assets


266

ฉันรู้ว่าไฟล์ในresไดเรกทอรีสามารถเข้าถึงได้จากR.classในขณะที่สินทรัพย์ทำงานเหมือนระบบไฟล์ แต่ฉันต้องการทราบโดยทั่วไปว่าเมื่อใดควรใช้อย่างใดอย่างหนึ่ง
ใครสามารถช่วยฉันในการรู้ความแตกต่างที่แท้จริงระหว่างความละเอียดและสินทรัพย์

คำตอบ:


284

ด้วยทรัพยากรมีการสนับสนุนในตัวสำหรับการให้ทางเลือกสำหรับภาษาต่าง ๆ เวอร์ชันของระบบปฏิบัติการการวางแนวหน้าจอ ฯลฯ ตามที่อธิบายไว้ที่นี่ที่นี่ไม่มีสิ่งใดที่พร้อมใช้งานกับเนื้อหา นอกจากนี้หลายส่วนของ API ยังสนับสนุนการใช้ตัวระบุทรัพยากร ในที่สุดชื่อของทรัพยากรจะถูกเปลี่ยนเป็นชื่อเขตข้อมูลคงที่ที่มีการตรวจสอบในเวลารวบรวมดังนั้นจึงมีโอกาสน้อยกว่าที่จะไม่ตรงกันระหว่างรหัสและทรัพยากรด้วยตนเอง ไม่มีสิ่งใดที่เกี่ยวข้องกับสินทรัพย์

เหตุใดจึงต้องมีโฟลเดอร์สินทรัพย์เลย หากคุณต้องการคำนวณสินทรัพย์ที่คุณต้องการใช้ในขณะใช้งานมันค่อนข้างง่าย ด้วยทรัพยากรคุณจะต้องประกาศรายการของรหัสทรัพยากรทั้งหมดที่อาจใช้และคำนวณดัชนีลงในรายการ (นี่เป็นชนิดที่น่าอึดอัดใจและแนะนำโอกาสในการเกิดข้อผิดพลาดหากชุดของการเปลี่ยนแปลงทรัพยากรในวงจรการพัฒนา) (แก้ไข: คุณสามารถเรียก ID ทรัพยากรตามชื่อโดยใช้getIdentifierแต่สิ่งนี้จะเสียประโยชน์จากการตรวจสอบเวลาคอมไพล์) ยังถูกจัดระเบียบเป็นลำดับชั้นของโฟลเดอร์ซึ่งไม่ได้รับการสนับสนุนจากทรัพยากร มันเป็นวิธีการจัดการข้อมูลที่แตกต่าง แม้ว่าทรัพยากรครอบคลุมกรณีส่วนใหญ่ แต่สินทรัพย์มีการใช้งานเป็นครั้งคราว

ความแตกต่างอีกประการหนึ่ง: ทรัพยากรที่กำหนดไว้ในโครงการห้องสมุดจะถูกนำเข้าโดยอัตโนมัติไปยังโครงการแอปพลิเคชันที่ขึ้นอยู่กับห้องสมุด สำหรับสินทรัพย์นั่นไม่ได้เกิดขึ้น ไฟล์สินทรัพย์ต้องมีอยู่ในไดเรกทอรีสินทรัพย์ของโครงการแอปพลิเคชัน [แก้ไข: ด้วยระบบการสร้างแบบ Gradle-basedใหม่ของ Android (ใช้กับ Android Studio) สิ่งนี้ไม่เป็นความจริงอีกต่อไป ไดเรกทอรีสินทรัพย์สำหรับโครงการห้องสมุดถูกรวมไว้ในไฟล์. aar ดังนั้นสินทรัพย์ที่กำหนดไว้ในโครงการห้องสมุดจะรวมเข้ากับโครงการแอปพลิเคชัน (ดังนั้นจึงไม่จำเป็นต้องมีอยู่ใน/assetsไดเรกทอรีของแอปพลิเคชัน

แก้ไข: มีความแตกต่างอื่นเกิดขึ้นถ้าคุณต้องการจัดทำฟอนต์แบบกำหนดเองด้วยแอปของคุณ มีการเรียก APIเพื่อสร้างTypefaceจากไฟล์ฟอนต์ที่เก็บไว้ในระบบไฟล์หรือในassets/ไดเรกทอรีของแอปของคุณ แต่ไม่มี API ที่จะสร้างTypefaceจากไฟล์ฟอนต์ที่เก็บไว้ในres/ไดเรกทอรี (หรือจากInputStreamซึ่งจะอนุญาตให้ใช้res/ไดเรกทอรี) [ หมายเหตุ:ด้วย Android O (ตอนนี้พร้อมใช้งานในหน้าตัวอย่างแบบอัลฟา) คุณจะสามารถรวมแบบอักษรที่กำหนดเองเป็นทรัพยากรได้ ดูคำอธิบายที่นี่ของคุณลักษณะที่ค้างชำระนาน อย่างไรก็ตามตราบใดที่ระดับ API ต่ำสุดของคุณคือ 25 หรือน้อยกว่าคุณจะต้องติดกับแบบอักษรที่กำหนดเองของบรรจุภัณฑ์เป็นสินทรัพย์แทนที่จะเป็นทรัพยากร]


1
resย่อมาจากทรัพยากรแล้วสิ่งที่จะassetsหมายถึงอะไร
Vivek Warde

40
@vwvwvwvwvwvwvwvwvwvw - อืม ... มันไม่ "ยืนหยัดเพื่อ" อะไรเลย มันหมายถึง "ทรัพย์สิน" (เช่นเดียวกับพหูพจน์ของสินทรัพย์คำภาษาอังกฤษ: สิ่งที่มีประโยชน์หรือมีค่า )
Ted Hopp

1
เป็นไปได้ไหมที่จะเขียนไปยังไฟล์ในraw/ไดเรกทอรี?
เจ้าชาย

6
@Prince - ไม่ทุกอย่างใน/resไดเรกทอรีและ '/ assets' นั้นเป็นแบบอ่านอย่างเดียวเนื่องจากถูกทำแพ็กเกจไว้ในไฟล์. apk
Ted Hopp

เราสามารถใส่ไฟล์ apk ลงในโฟลเดอร์ทรัพย์สินและเมื่อผู้ใช้คลิกที่ UI นั้นติดตั้ง apk นั้น
Vivek Mishra

63

ทั้งคู่คล้ายกันมาก ความแตกต่างสำคัญที่แท้จริงระหว่างคนทั้งสองที่อยู่ในresไดเรกทอรีแต่ละไฟล์จะได้รับก่อนรวบรวมซึ่งสามารถเข้าถึงได้อย่างง่ายดายผ่านทางID R.id.[res id]สิ่งนี้มีประโยชน์ในการเข้าถึงรูปภาพเสียงไอคอนอย่างรวดเร็วและง่ายดาย

assetsไดเรกทอรีมีมากขึ้นเช่นระบบแฟ้มและให้เสรีภาพมากขึ้นที่จะนำไฟล์ที่คุณต้องการในการมี จากนั้นคุณสามารถเข้าถึงแต่ละไฟล์ในระบบนั้นได้เช่นเดียวกับเมื่อคุณเข้าถึงไฟล์ใด ๆ ในระบบไฟล์ผ่าน Java ไดเรกทอรีนี้เหมาะสำหรับสิ่งต่าง ๆ เช่นรายละเอียดเกมพจนานุกรม ... ฯลฯ หวังว่าจะช่วย


5
ถ้าเราต้องการเพิ่ม external_fonts ในแอพของเราเราจะใส่ไว้ในโฟลเดอร์ทรัพย์สิน
Tushar Pandey

1
@TusharPandey ตอนนี้เราไม่ต้องใส่แบบอักษรในAssetsโฟลเดอร์ระบบ Android ตอนนี้มีfontsไดเรกทอรีและเราสามารถใส่ไฟล์แบบอักษรที่กำหนดเองของเราที่นั่นหรือเราสามารถดาวน์โหลด Android studio สำหรับเรา
CopsOnRoad

@ แจ็คมันสำหรับโอรีโอ
Tushar Pandey

1
@TusharPandey มีการเพิ่มใน Oreo แต่ได้รับการส่งกลับไปยัง Android Support Library ย้อนกลับไปที่ระดับ API 16
CopsOnRoad

36

ฉันรู้ว่ามันเก่า แต่เพียงเพื่อให้ชัดเจนมีคำอธิบายของแต่ละคนในเอกสาร Android อย่างเป็นทางการ:

จากhttp://developer.android.com/tools/projects/index.html

assets/

นี่ว่างเปล่า คุณสามารถใช้มันเพื่อจัดเก็บไฟล์สินทรัพย์ดิบ ไฟล์ที่คุณบันทึกที่นี่จะถูกรวบรวมเป็นไฟล์. apk ตามที่เป็นอยู่และชื่อไฟล์ดั้งเดิมจะถูกเก็บรักษาไว้ คุณสามารถนำทางไดเรกทอรีนี้ในลักษณะเดียวกับระบบไฟล์ทั่วไปโดยใช้ URIs และอ่านไฟล์เป็นสตรีมไบต์โดยใช้ AssetManager ตัวอย่างเช่นนี่เป็นตำแหน่งที่ดีสำหรับพื้นผิวและข้อมูลเกม

res/raw/

สำหรับไฟล์สินทรัพย์ดิบโดยพลการ การบันทึกไฟล์เนื้อหาที่นี่แทนที่จะเป็นในไฟล์สินทรัพย์ / ไดเรกทอรีจะแตกต่างกันไปตามวิธีที่คุณเข้าถึง ไฟล์เหล่านี้ถูกประมวลผลโดย aapt และต้องอ้างอิงจากแอปพลิเคชันโดยใช้ตัวระบุทรัพยากรในคลาส R ตัวอย่างเช่นนี่เป็นสถานที่ที่ดีสำหรับสื่อเช่นไฟล์ MP3 หรือ Ogg


4
ฉันคิดว่าสิ่งนี้ทำให้เกิดความสับสน - ทั้งพื้นผิวและไฟล์ ogg เป็นข้อมูลจำนวนมากที่คุณป้อนเข้าสู่ userland API (openGL / MediaPlayer) ... ทำไมพวกเขาถึงเลือกปฏิบัติที่นี่

9

ต่อไปนี้เป็นประเด็นสำคัญ:

  1. ไฟล์ Raw ต้องมีชื่อที่เป็นตัวระบุ Java ที่ถูกต้องในขณะที่ไฟล์ในสินทรัพย์ไม่มีข้อ จำกัด ตำแหน่งที่ตั้งและชื่อ กล่าวอีกนัยหนึ่งพวกเขาสามารถจัดกลุ่มในไดเรกทอรีใดก็ได้ที่เราต้องการ
  2. ไฟล์ Raw ง่ายต่อการอ้างถึงจาก Java และจาก xml (เช่นคุณสามารถอ้างถึงไฟล์ในรูปแบบ raw จากไฟล์ Manifest หรือไฟล์ xml อื่น ๆ )
  3. การบันทึกไฟล์เนื้อหาที่นี่แทนที่จะเป็นในสินทรัพย์ / ไดเรกทอรีจะแตกต่างกันในวิธีที่คุณเข้าถึงไฟล์ตามที่ได้รับการบันทึกไว้ที่นี่ http://developer.android.com/tools/projects/index.html http://developer.android.com/tools/projects/index.html
  4. ทรัพยากรที่กำหนดไว้ในโครงการห้องสมุดจะถูกนำเข้าโดยอัตโนมัติไปยังโครงการแอปพลิเคชันที่ขึ้นอยู่กับห้องสมุด สำหรับสินทรัพย์นั่นไม่ได้เกิดขึ้น ไฟล์สินทรัพย์ต้องมีอยู่ในไดเรกทอรีสินทรัพย์ของโครงการแอปพลิเคชัน
  5. ไดเรคทอรีสินทรัพย์เป็นเหมือนระบบไฟล์ที่ให้อิสระในการใส่ไฟล์ใด ๆ ที่คุณต้องการ จากนั้นคุณสามารถเข้าถึงแต่ละไฟล์ในระบบนั้นได้เช่นเดียวกับเมื่อคุณเข้าถึงไฟล์ใด ๆ ในระบบไฟล์ผ่าน Java เช่นไฟล์ข้อมูลเกม, แบบอักษร, พื้นผิว ฯลฯ
  6. ซึ่งแตกต่างจากทรัพยากรสินทรัพย์สามารถจัดเป็นโฟลเดอร์ย่อยในไดเรกทอรีสินทรัพย์อย่างไรก็ตามสิ่งเดียวที่คุณสามารถทำได้กับเนื้อหาคือรับกระแสข้อมูล ดังนั้นจึงไม่มีความเหมาะสมในการจัดเก็บสตริงหรือบิตแมปในเนื้อหา แต่คุณสามารถจัดเก็บข้อมูลรูปแบบที่กำหนดเองเช่นพจนานุกรมแก้ไขการป้อนข้อมูลหรือแผนที่เกม
  7. Raw สามารถให้คุณตรวจสอบเวลาการคอมไพล์ได้โดยการสร้างไฟล์ R.java ของคุณอย่างไรก็ตามหากคุณต้องการคัดลอกฐานข้อมูลของคุณไปยังไดเรกทอรีส่วนตัวคุณสามารถใช้สินทรัพย์ที่ทำขึ้นเพื่อสตรีมมิ่ง

ข้อสรุป

  1. Android API มีเฟรมเวิร์กทรัพยากรที่สะดวกสบายมากซึ่งได้รับการปรับให้เหมาะกับกรณีการใช้งานทั่วไปสำหรับแอพมือถือต่างๆ คุณควรใช้ทรัพยากรหลักและพยายามใช้ทุกที่ที่เป็นไปได้
  2. อย่างไรก็ตามหากคุณต้องการความยืดหยุ่นมากขึ้นสำหรับกรณีพิเศษของคุณสินทรัพย์อยู่ที่นั่นเพื่อให้ API ระดับต่ำกว่าที่ช่วยให้การจัดระเบียบและการประมวลผลทรัพยากรของคุณมีอิสระในระดับที่สูงขึ้น

ตามคำตอบที่ยอมรับแล้วจุดที่ 4 ไม่เป็นความจริงอีกต่อไปสำหรับโครงการที่ใช้ระบบการสร้างแบบ Gradle เนื้อหาจากไลบรารีถูกรวมเข้ากับการรวบรวมทรัพย์สินของโครงการแอปพลิเคชัน
Venryx

4

หากคุณต้องการอ้างอิงไฟล์เหล่านี้ใน Java Code คุณจะต้องใส่ไฟล์ของคุณลงในไดเรกทอรี "res"

และไฟล์ทั้งหมดในโฟลเดอร์ res จะถูกทำดัชนีในไฟล์ R ซึ่งทำให้โหลดได้เร็วขึ้น (และง่ายกว่ามาก!)


6
คุณสามารถเข้าถึงไฟล์ในสินทรัพย์จาก Java ได้เช่นกัน
Heiko Rupp

2
ใช่ แต่ไม่ได้จัดทำดัชนี -> จะช้าลงปัญหาที่แท้จริงคือการพัฒนาอุปกรณ์พกพา
L.Butz

ดังนั้นอะไรคือความแตกต่างระหว่าง res / raw และสินทรัพย์ res / raw จะถูกทำดัชนีด้วยหรือไม่
anticafe

ตรวจสอบโพสต์จาก @TedHopp - เขานำคำตอบที่ชัดเจนจริงๆ
L.Butz

1

ใช้ทรัพย์สินอย่างระบบไฟล์เพื่อถ่ายโอนไฟล์ทุกชนิด และใช้ res เพื่อจัดเก็บสิ่งที่ทำไว้สำหรับเลย์เอาต์รูปภาพค่า


0

Ted Hopp ตอบคำถามนี้ค่อนข้างดี ฉันใช้ res / raw สำหรับไฟล์ opengl texture และ shader ฉันกำลังคิดที่จะย้ายพวกเขาไปยังไดเรกทอรีสินทรัพย์เพื่อให้องค์กรที่มีลำดับชั้น

หัวข้อนี้ทำให้ฉันไม่เชื่อ ก่อนอื่นเพราะฉันชอบใช้รหัสทรัพยากรที่ไม่ซ้ำใคร ข้อสองเพราะมันง่ายมากที่จะใช้ InputStream / openRawResource หรือ BitmapFactory เพื่ออ่านในไฟล์ ข้อที่สามเพราะมีประโยชน์มากที่จะสามารถใช้ในห้องสมุดแบบพกพา


1
จุดที่ 2 ของการสนับสนุน InputStreams และ BitmapFactory เป็นจริงสำหรับทั้งทรัพยากรและสินทรัพย์ (ดูที่นี่: stackoverflow.com/a/8501428/2441655 ) ใช้กับจุดที่ 3 ไม่ได้อีกต่อไป (ดูคำตอบที่ยอมรับ)
Venryx

-5

เนื้อหามีวิธีการรวมไฟล์โดยพลการเช่นข้อความ, xml, ฟอนต์, เพลงและวิดีโอในแอปพลิเคชันของคุณ หากคุณพยายามรวมไฟล์เหล่านี้เป็น "ทรัพยากร" Android จะประมวลผลไฟล์เหล่านั้นลงในระบบทรัพยากรและคุณจะไม่สามารถรับข้อมูลดิบได้ หากคุณต้องการเข้าถึงข้อมูลที่ไม่ถูกแตะต้องสินทรัพย์เป็นวิธีหนึ่งในการดำเนินการ


5
สิ่งนี้ไม่ถูกต้อง หากคุณใส่ข้อมูลในres/raw, openRawResource(resourceName)คุณจะได้รับข้อมูลดิบโดยใช้
Ted Hopp

ฉันมีไฟล์ opengles texture และ shader ในไลบรารี ฉันต้องใช้ res / raw เพื่อเก็บไว้ ฉันใช้ InputStream และ BitmapFactory เพื่ออ่าน ฉันจะเพิ่มนี่เป็นความคิดเห็นอิสระ
dturvene

ดูเหมือนว่าคัดลอกมาจากเอกสารของ Xamarin Microsoft ให้ที่มาของคุณเมื่อคัดลอกข้อความ docs.microsoft.com/en-us/xamarin/android/app-fundamentals/ …
Sjoerd Pottuit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.