วิธีปรับปรุงประสิทธิภาพสำหรับ resources.getDrawable

ฉันมีกิจกรรมที่โหลดภาพ png สามภาพ บน hdpi คือ 20kb, 148kb และ 190kb นี่คือรหัสที่ฉันกำลังโหลดด้วย:

Drawable bronzePlaque = resources.getDrawable(R.drawable.bronze_plaque);
Drawable silverPlaque = resources.getDrawable(R.drawable.silver_plaque);
Drawable goldPlaque = resources.getDrawable(R.drawable.gold_plaque);

ดูเหมือนว่าการโทรเหล่านั้นเพียงอย่างเดียวจะใช้เวลาประมาณ 500 มิลลิวินาที ซึ่งทำให้เกิดความล่าช้าอย่างเห็นได้ชัดเมื่อโหลดกิจกรรมนั้น

ฉันไม่แน่ใจว่าต้องใช้เวลานานแค่ไหนเนื่องจากขนาดของรูปภาพเทียบกับการรวบรวมขยะ / ขนาดฮีปที่เพิ่มขึ้น แต่ฉันต้องการลองทำอะไรบางอย่างเพื่อปรับปรุง มีวิธีที่ฉันสามารถให้เครื่องเสมือนขยายฮีปและรวบรวมขยะได้อย่างถูกต้องเพียงครั้งเดียวสำหรับการจัดสรรทั้งสามครั้งนั้นหรือไม่

นี่คือเอาต์พุต logcat สำหรับสามบรรทัดนั้น (และสำหรับระบบพิมพ์ getTimeInMillis รอบๆ บรรทัดเหล่านั้น)

03-23 14:05:57.260: I/System.out(30302): time: 1395608757267
03-23 14:05:57.370: D/dalvikvm(30302): GC_FOR_ALLOC freed 39K, 4% free 7990K/8272K, paused 20ms, total 20ms
03-23 14:05:57.370: I/dalvikvm-heap(30302): Grow heap (frag case) to 8.968MB for 1188160-byte allocation
03-23 14:05:57.390: D/dalvikvm(30302): GC_FOR_ALLOC freed 1K, 4% free 9149K/9436K, paused 19ms, total 19ms
03-23 14:05:57.540: D/dalvikvm(30302): GC_FOR_ALLOC freed 1K, 4% free 9148K/9436K, paused 15ms, total 16ms
03-23 14:05:57.540: I/dalvikvm-heap(30302): Grow heap (frag case) to 10.245MB for 1340008-byte allocation
03-23 14:05:57.560: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 10457K/10748K, paused 19ms, total 19ms
03-23 14:05:57.720: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 10457K/10748K, paused 15ms, total 15ms
03-23 14:05:57.720: I/dalvikvm-heap(30302): Grow heap (frag case) to 11.482MB for 1297384-byte allocation
03-23 14:05:57.740: D/dalvikvm(30302): GC_FOR_ALLOC freed <1K, 3% free 11724K/12016K, paused 18ms, total 18ms
03-23 14:05:57.760: I/System.out(30302): time: 1395608757770

ฉันรู้ว่าหลังจากโหลดกิจกรรมนั้นแล้ว เมื่อโหลดกิจกรรมได้เร็วกว่ามากในภายหลัง ฉันควรโหลดรูปภาพเหล่านั้นหนึ่งครั้งในเวลาโหลดแอปเพื่อช่วยป้องกันไม่ให้ฮีปเติบโตหรือเก็บขยะอย่างเจ็บปวดหรือไม่ ฉันอยากให้มีความล่าช้าครึ่งวินาทีที่โหลดล่วงหน้ามากกว่าที่จะเกิดขึ้นเมื่อคลิกกิจกรรม


person CorayThan    schedule 23.03.2014    source แหล่งที่มา
comment
รูปภาพมีขนาดเท่าไร?   -  person Simon    schedule 24.03.2014
comment
750x502 พิกเซล -- 20kb, 750x567 พิกเซล -- 149kb และ 750x549 พิกเซล -- 190kb เป็นภาพพื้นหลังสำหรับ scrollview   -  person CorayThan    schedule 24.03.2014


คำตอบ (2)


ลองโหลดภาพเหล่านี้จากกระทู้อื่น (เช่น ไม่ใช่หัวข้อหลัก) แทน นอกจาก ~100ms ที่ใช้ใน gc แล้ว 500ms ที่เหลือยังใช้ในการโหลดข้อมูลจากระบบไฟล์และคลายการบีบอัดข้อมูล JPG ลงในบิตแมป

ฉันรู้ว่าหลังจากโหลดกิจกรรมนั้นแล้ว เมื่อโหลดกิจกรรมได้เร็วกว่ามากในภายหลัง ฉันควรโหลดรูปภาพเหล่านั้นหนึ่งครั้งในเวลาโหลดแอปเพื่อช่วยป้องกันไม่ให้ฮีปเติบโตหรือเก็บขยะอย่างเจ็บปวดหรือไม่

เว้นแต่ว่าคุณจงใจยึดบิตแมปที่ถอดรหัสไว้ไว้ มิฉะนั้นทรัพยากรจะปล่อย Drawable/บิตแมปที่แคชไว้ได้อย่างอิสระตามที่เห็นสมควร โปรดทราบว่ารูปภาพจะใช้พื้นที่ 750x502x4 + 750x567x4 + 750x549x4 =~4.5 MB RAM โดยตั้งใจที่จะยึดไว้อาจมีการแตกสาขาอื่นๆ เช่น OoM บนอุปกรณ์รุ่นเก่า (Nexus One มี RAM สูงสุดเพียง 16 MB ต่อกระบวนการ/แอป) และอาจ ทำให้แอปของคุณถูกลบออกจากหน่วยความจำเร็วขึ้นเมื่ออยู่ในพื้นหลังและระบบปฏิบัติการต้องการ RAM เพิ่มขึ้น

person Kai    schedule 24.03.2014
comment
ใช่ ฉันไม่ต้องการที่จะยึดติดกับพวกเขาจริงๆ สำหรับตอนนี้ ฉันแค่โหลดมันในเมธอด onCreate สำหรับแอปพลิเคชัน ซึ่งดูเหมือนว่าจะลดความเจ็บปวดลงเล็กน้อยอย่างไม่สม่ำเสมอ กิจกรรมไม่สามารถแสดงได้จนกว่าจะโหลดเสร็จ ดังนั้นการโหลดกิจกรรมเหล่านั้นในเธรดอื่นคงไม่ได้ผลมากนักเว้นแต่ฉันต้องการสร้างแอนิเมชั่นในการโหลดหรืออะไรสักอย่าง - person CorayThan; 26.03.2014
comment
@CorayThan หากคุณกระตือรือร้นที่จะลดเวลาในการโหลดและกิจกรรมนี้ไม่ใช่กิจกรรมหลัก คุณสามารถโหลดข้อมูลไฟล์ดิบลงในหน่วยความจำในรูปแบบ byte[] เพื่อที่คุณจะได้ไม่ต้องโหลดเมื่อกิจกรรมนั้นเริ่มต้นขึ้น แน่นอนว่าก่อนที่จะไปตามเส้นทางนี้ คุณควรตรวจสอบส่วนการอ่านไฟล์เพื่อให้แน่ใจว่ามีประโยชน์อยู่ที่นั่น - person Kai; 26.03.2014

ดูเหมือนคุณจะโชคไม่ดีนัก คุณไม่สามารถเพิ่มฮีปบน Android ได้ตามที่คุณต้องการ (ไม่เหมือนในกระบวนการ JVM ปกติ) ดูที่นี่ รูปภาพขนาด 4 MB นั้นมากเกินไป

และดูเหมือนว่าคุณจะมีวิธีแก้ปัญหาอยู่แล้ว โปรดโหลดล่วงหน้า

person Eugene    schedule 25.03.2014