การเพิ่มประสิทธิภาพหน่วยความจำเป็นสิ่งสำคัญในการรับประกันประสิทธิภาพที่ราบรื่น ป้องกันไม่ให้แอปขัดข้อง และรักษาเสถียรภาพของระบบและสถานะของแพลตฟอร์ม แม้ว่าควรมีการตรวจสอบและเพิ่มประสิทธิภาพการใช้หน่วยความจำในทุกแอป แต่แอปเนื้อหาสำหรับอุปกรณ์ทีวีมีปัญหาเฉพาะที่แตกต่างจากแอป Android ทั่วไปสำหรับอุปกรณ์พกพา
การใช้หน่วยความจำสูงอาจทำให้เกิดปัญหาเกี่ยวกับลักษณะการทำงานของแอปและระบบ ซึ่งรวมถึง
- ตัวแอปเองอาจทำงานช้าหรือหน่วง หรือในกรณีที่แย่ที่สุดอาจถูกปิด
- บริการของระบบที่ผู้ใช้มองเห็น (การควบคุมระดับเสียง การตั้งค่ารูปภาพ แดชบอร์ด ผู้ช่วยเสียง ฯลฯ) จะทำงานช้ามากหรืออาจไม่ทำงานเลย
- กระบวนการของดีมอนการหยุดทำงานเนื่องจากหน่วยความจำไม่เพียงพอ (LMK) อาจ ตอบสนองต่อการใช้หน่วยความจำสูงด้วยการหยุดกระบวนการที่จำเป็นน้อยที่สุด จากนั้น คอมโพเนนต์เหล่านี้อาจรีสตาร์ทในเวลาอันสั้น ซึ่งจะทำให้เกิดการแย่งชิงทรัพยากรเพิ่มเติม ซึ่งอาจส่งผลกระทบโดยตรงต่อแอปที่ทำงานอยู่เบื้องหน้า
- การเปลี่ยนไปใช้ Launcher อาจล่าช้าอย่างมาก และทำให้แอปที่ทำงานอยู่เบื้องหน้าดูเหมือนไม่ตอบสนองจนกว่าการเปลี่ยนผ่านจะเสร็จสิ้น
- ระบบอาจเริ่มใช้การเรียกคืนโดยตรง โดยหยุดการดำเนินการของเธรดชั่วคราวขณะรอการจัดสรรหน่วยความจำ ปัญหานี้อาจเกิดขึ้นกับเทรดใดก็ได้ เช่น เทรดหลักหรือเทรดที่เกี่ยวข้องกับตัวแปลงรหัส ซึ่งอาจทำให้เฟรมเสียงและวิดีโอหลุด รวมถึง UI ขัดข้อง
ข้อควรพิจารณาเกี่ยวกับหน่วยความจำในอุปกรณ์ทีวี
โดยปกติแล้ว อุปกรณ์ทีวีจะมีหน่วยความจำน้อยกว่าโทรศัพท์หรือแท็บเล็ตมาก ตัวอย่างเช่น การกำหนดค่าที่เราเห็นในทีวีคือ RAM 1 GB และความละเอียดวิดีโอ 1080p ในขณะเดียวกัน แอปทีวีส่วนใหญ่ก็มีฟีเจอร์ที่คล้ายกัน จึงมีการติดตั้งใช้งานที่คล้ายกันและความท้าทายที่พบบ่อย สถานการณ์ทั้ง 2 นี้ทำให้เกิดปัญหาที่ไม่พบในอุปกรณ์และแอปประเภทอื่นๆ ดังนี้
- โดยปกติแล้ว แอปทีวีสื่อจะประกอบด้วยทั้งมุมมองรูปภาพแบบตารางกริดและรูปภาพพื้นหลังแบบเต็มหน้าจอ ซึ่งต้องโหลดรูปภาพจำนวนมากไปยังหน่วยความจำในระยะเวลาอันสั้น
- แอปทีวีเล่นสตรีมมัลติมีเดียซึ่งต้องจัดสรรหน่วยความจำจำนวนหนึ่ง เพื่อเล่นวิดีโอและเสียง และต้องมีบัฟเฟอร์สื่อจำนวนมาก เพื่อให้เล่นได้อย่างราบรื่น
- ฟีเจอร์สื่อเพิ่มเติม (การกรอ การเปลี่ยนตอน การเปลี่ยนแทร็กเสียง ฯลฯ) อาจใช้หน่วยความจำมากขึ้นหากไม่ได้ใช้งานอย่างถูกต้อง
ทำความเข้าใจเกี่ยวกับอุปกรณ์ทีวี
คู่มือนี้มุ่งเน้นที่การใช้งานหน่วยความจำของแอปและเป้าหมายหน่วยความจำสำหรับอุปกรณ์ที่มี RAM ต่ำเป็นหลัก
ในอุปกรณ์ทีวี ให้พิจารณาลักษณะต่อไปนี้
- หน่วยความจำของอุปกรณ์: ปริมาณหน่วยความจำเข้าถึงโดยสุ่ม (RAM) ที่ อุปกรณ์ติดตั้งไว้
- ความละเอียด UI ของอุปกรณ์: ความละเอียดที่อุปกรณ์ใช้ในการแสดงผล UI ของระบบปฏิบัติการ และแอปพลิเคชัน โดยปกติแล้วความละเอียดนี้จะต่ำกว่าความละเอียดวิดีโอของอุปกรณ์
- ความละเอียดของวิดีโอ: ความละเอียดสูงสุดที่อุปกรณ์สามารถเล่นวิดีโอได้
ซึ่งจะนำไปสู่การจัดหมวดหมู่อุปกรณ์ประเภทต่างๆ และวิธีที่อุปกรณ์ควรใช้หน่วยความจำ
สรุปอุปกรณ์ทีวี
| หน่วยความจำของอุปกรณ์ | ความละเอียดวิดีโอของอุปกรณ์ | ความละเอียดของ UI ของอุปกรณ์ | isLowRAMDevice() |
|---|---|---|---|
| 1 GB | 1080p | 720p | ใช่ |
| 1.5 GB | 2160p | 1080p | ใช่ |
| ≥1.5 GB | 1080p | 720p หรือ 1080p | ไม่* |
| ≥2 GB | 2160p | 1080p | ไม่* |
อุปกรณ์ทีวีที่มี RAM ต่ำ
อุปกรณ์เหล่านี้อยู่ในสถานการณ์ที่หน่วยความจำมีจำกัดและจะรายงาน
ActivityManager.isLowRAMDevice()
เป็นจริง แอปพลิเคชันที่ทำงานบนอุปกรณ์ทีวีที่มี RAM น้อยต้องใช้
มาตรการควบคุมหน่วยความจำเพิ่มเติม
เราถือว่าอุปกรณ์ที่มีลักษณะต่อไปนี้จัดอยู่ในหมวดหมู่นี้
- อุปกรณ์ 1 GB: RAM 1 GB, ความละเอียด UI 720p/HD (1280x720), ความละเอียดวิดีโอ 1080p/FullHD (1920x1080)
- อุปกรณ์ 1.5 GB: RAM 1.5 GB, ความละเอียด UI 1080p/FullHD (1920x1080), ความละเอียดวิดีโอ 2160p/UltraHD/4K (3840x2160)
- สถานการณ์อื่นๆ ที่ OEM กำหนดแฟล็ก
ActivityManager.isLowRAMDevice()เนื่องจากข้อจำกัดด้านหน่วยความจำเพิ่มเติม
อุปกรณ์ทีวีทั่วไป
อุปกรณ์เหล่านี้จึงไม่ประสบปัญหาหน่วยความจำเต็มอย่างรุนแรง เรา พิจารณาว่าอุปกรณ์เหล่านี้มีลักษณะดังนี้
- RAM ≥1.5 GB, UI 720p หรือ 1080p และความละเอียดวิดีโอ 1080p
- RAM ≥2 GB, UI 1080p และความละเอียดวิดีโอ 1080p หรือ 2160p
อย่างไรก็ตาม ไม่ได้หมายความว่าแอปไม่ควรคำนึงถึงการใช้งานหน่วยความจำในอุปกรณ์เหล่านี้ เนื่องจากการใช้หน่วยความจำในทางที่ผิดบางอย่างอาจยังคงทำให้หน่วยความจำที่มีอยู่หมดไปและทำงานได้ไม่ดี
เป้าหมายหน่วยความจำในอุปกรณ์ทีวีที่มี RAM น้อย
เมื่อวัดหน่วยความจำในอุปกรณ์เหล่านี้ เราขอแนะนำอย่างยิ่งให้ตรวจสอบ ทุกส่วนของหน่วยความจำโดยใช้ โปรไฟล์หน่วยความจำของ Android Studio แอปทีวี ควรสร้างโปรไฟล์การใช้งานหน่วยความจำและพยายามให้หมวดหมู่ของแอปอยู่ต่ำกว่า เกณฑ์ที่เรากำหนดไว้ในส่วนนี้

ในส่วนวิธีนับหน่วยความจำ คุณจะเห็นคำอธิบายโดยละเอียดเกี่ยวกับตัวเลขหน่วยความจำที่รายงาน สำหรับคำจำกัดความของเกณฑ์สำหรับแอปทีวี เราจะมุ่งเน้นไปที่หมวดหมู่หน่วยความจำ 3 หมวดหมู่ ได้แก่
- Anonymous + Swap: ประกอบด้วยหน่วยความจำที่จัดสรร Java + Native + Stack ใน Android Studio
- กราฟิก: รายงานโดยตรงในเครื่องมือโปรไฟล์ โดยทั่วไปจะประกอบด้วย พื้นผิวของกราฟิก
- ไฟล์: รายงานเป็นหมวดหมู่ "โค้ด" + "อื่นๆ" ใน Android Studio
เมื่อใช้คำจำกัดความเหล่านี้ ตารางต่อไปนี้จะระบุมูลค่าสูงสุดที่กลุ่มหน่วยความจำแต่ละประเภทควรใช้
| ประเภทหน่วยความจำ | Purpose | เป้าหมายการใช้งาน (1 GB) |
|---|---|---|
| ไม่ระบุตัวตน + สลับ (Java + เนทีฟ + สแต็ก) | ใช้สำหรับการจัดสรร บัฟเฟอร์สื่อ ตัวแปร และงานอื่นๆ ที่ใช้หน่วยความจำสูง | < 160 MB |
| กราฟิก | ใช้โดย GPU สำหรับเท็กซ์เจอร์และบัฟเฟอร์ที่เกี่ยวข้องกับการแสดงผล | 30-40 MB |
| ไฟล์ | ใช้สำหรับหน้าโค้ดและไฟล์ในหน่วยความจำ | 60-80 MB |
หน่วยความจำรวมสูงสุด (Anon+Swap + Graphics + File) ต้องไม่เกิน ค่าต่อไปนี้
- 280 MB ของการใช้งานหน่วยความจำทั้งหมด (Anon+Swap + Graphics + File) สำหรับอุปกรณ์ RAM ต่ำที่มีขนาด 1 GB
เราขอแนะนำไม่ให้เกินขีดจำกัดต่อไปนี้
- การใช้งานหน่วยความจำ 200 MB ใน (Anon+Swap + Graphics)
หน่วยความจำไฟล์
คำแนะนำทั่วไปสำหรับหน่วยความจำที่สำรองข้อมูลไว้ในไฟล์มีดังนี้
- โดยทั่วไปแล้ว การจัดการหน่วยความจำของระบบปฏิบัติการจะจัดการหน่วยความจำของไฟล์ได้ดี
- เราไม่พบว่าการดำเนินการนี้เป็นสาเหตุหลักที่ทำให้หน่วยความจำใกล้เต็มในขณะนี้
อย่างไรก็ตาม เมื่อจัดการกับหน่วยความจำของไฟล์โดยทั่วไป ให้ทำดังนี้
- อย่ารวมไลบรารีที่ไม่ได้ใช้ไว้ในการสร้าง และใช้ชุดย่อยขนาดเล็กของไลบรารีแทนที่จะใช้ไลบรารีทั้งหมดเมื่อเป็นไปได้
- อย่าเปิดไฟล์ขนาดใหญ่ไว้ในหน่วยความจำและปิดทันทีที่ใช้งานเสร็จ
- ลดขนาดโค้ดที่คอมไพล์แล้วสำหรับคลาส Java และ Kotlin โปรดดูคำแนะนำลดขนาด สร้างความสับสน และเพิ่มประสิทธิภาพแอป
คำแนะนำเฉพาะสำหรับทีวี
ส่วนนี้จะให้คำแนะนำที่เฉพาะเจาะจงสำหรับการใช้งานหน่วยความจำในอุปกรณ์ทีวี
หน่วยความจำกราฟิก
ใช้รูปแบบและความละเอียดของรูปภาพที่เหมาะสม
- อย่าโหลดรูปภาพที่มีความละเอียดสูงกว่าความละเอียดของ UI ของอุปกรณ์ เช่น รูปภาพ 1080p ควรลดขนาดเป็น 720p ในอุปกรณ์ UI 720p
- ใช้บิตแมปที่อิงฮาร์ดแวร์เมื่อเป็นไปได้
- ในไลบรารี เช่น Glide ให้เปิดใช้ฟีเจอร์
Downsampler.ALLOW_HARDWARE_CONFIGซึ่งปิดใช้อยู่โดยค่าเริ่มต้น การเปิดใช้ตัวเลือกนี้จะช่วยหลีกเลี่ยงการทำซ้ำบิตแมป ซึ่งปกติจะอยู่ในทั้งหน่วยความจำกราฟิกและหน่วยความจำที่ไม่ระบุตัวตน
- ในไลบรารี เช่น Glide ให้เปิดใช้ฟีเจอร์
- หลีกเลี่ยงการแสดงผลระดับกลางและการแสดงผลซ้ำ
- ซึ่งสามารถระบุได้ด้วย Android GPU Inspector ดังนี้
- ดูในส่วน "พื้นผิว" เพื่อหารูปภาพที่เป็นขั้นตอนในการ เรนเดอร์ขั้นสุดท้าย ไม่ใช่เพียงองค์ประกอบที่ประกอบกันเป็นพื้นผิว ซึ่งโดยทั่วไปแล้ว มักเรียกว่า"การเรนเดอร์ขั้นกลาง"
- สำหรับแอปพลิเคชัน Android SDK คุณมักจะนำสิ่งเหล่านี้ออกได้โดยใช้
แฟล็กเลย์เอาต์
forceHasOverlappedRendering:falseเพื่อปิดใช้การแสดงผลระดับกลางสำหรับเลย์เอาต์นี้ - ดูหลีกเลี่ยงการแสดงผลที่ซ้อนทับกัน เกี่ยวกับการแสดงผลที่ซ้อนทับกันเป็นแหล่งข้อมูลที่ยอดเยี่ยม
- หลีกเลี่ยงการโหลดรูปภาพที่มีตัวยึดตำแหน่งเมื่อเป็นไปได้ ให้ใช้
@android:color/หรือ@colorสำหรับพื้นผิวที่มีตัวยึดตำแหน่ง - หลีกเลี่ยงการคอมโพสิตรูปภาพหลายรูปในอุปกรณ์เมื่อสามารถทำการคอมโพสิตแบบออฟไลน์ได้ ควรโหลดรูปภาพสแตนด์อโลนมากกว่า การจัดองค์ประกอบรูปภาพจากรูปภาพที่ดาวน์โหลด
- โปรดทำตามคำแนะนำใน การจัดการบิตแมป เพื่อจัดการบิตแมปได้ดียิ่งขึ้น
หน่วยความจำ Anon+Swap
Anon+Swap ประกอบด้วยการจัดสรร Native + Java + Stack ในโปรไฟล์เลอร์หน่วยความจำของ Android Studio
ใช้
ActivityManager.isLowMemoryDevice()
เพื่อตรวจสอบว่าอุปกรณ์มีข้อจำกัดด้านหน่วยความจำหรือไม่ และปรับให้เข้ากับสถานการณ์นี้
โดยทำตามหลักเกณฑ์ต่อไปนี้
- สื่อ:
- ระบุขนาดตัวแปรสำหรับบัฟเฟอร์สื่อโดยขึ้นอยู่กับ RAM ของอุปกรณ์และความละเอียดในการเล่นวิดีโอ ซึ่งควรคิดเป็นเวลา 1 นาที
ของการเล่นวิดีโอ ดังนี้
- 40-60 MB สำหรับ 1 GB / 1080p
- 60-80 MB สำหรับ 1.5 GB / 1080p
- 80-100 MB สำหรับ 1.5 GB / 2160p
- 100-120 MB สำหรับ 2 GB / 2160p
- ล้างการจัดสรรหน่วยความจำสื่อฟรีเมื่อเปลี่ยนตอนเพื่อป้องกัน การเพิ่มขึ้นของหน่วยความจำที่ไม่ระบุตัวตนทั้งหมด
- ปล่อยและหยุดทรัพยากรสื่อทันทีเมื่อแอปถูกหยุด: ใช้การเรียกกลับของวงจรการทำงานของกิจกรรม
เพื่อจัดการทรัพยากรเสียงและวิดีโอ หากคุณไม่ได้ใช้แอปเสียง ให้หยุดเล่นเมื่อ
onStop()เกิดขึ้นใน กิจกรรมของคุณ ให้บันทึกงานทั้งหมดที่คุณกำลังทำอยู่ และตั้งค่าให้ระบบ ปล่อยทรัพยากร หากต้องการกำหนดเวลางานที่คุณอาจต้องใช้ในภายหลัง ดูส่วนงานและการปลุก- คุณสามารถใช้คอมโพเนนต์ที่รับรู้ถึงวงจร
เช่น
LiveDataและLifecycleOwnerเพื่อช่วยจัดการกับการเรียกวงจรของกิจกรรม - หากต้องการให้งานของคุณรับรู้ถึงวงจรของแอป คุณยังใช้โครูทีน Kotlin และ Kotlin Flow ได้ด้วย
- คุณสามารถใช้คอมโพเนนต์ที่รับรู้ถึงวงจร
เช่น
- โปรดคำนึงถึงหน่วยความจำของบัฟเฟอร์เมื่อกรอวิดีโอ: นักพัฒนาซอฟต์แวร์
มักจะจัดสรรเนื้อหาในอนาคตเพิ่มเติม 15-60 วินาทีเมื่อกรอเพื่อ
เตรียมวิดีโอให้พร้อมสำหรับผู้ใช้ แต่การทำเช่นนี้จะทำให้เกิดค่าใช้จ่ายเพิ่มเติมในหน่วยความจำ
โดยทั่วไปแล้ว อย่าใช้บัฟเฟอร์ในอนาคตเกิน 5 วินาทีจนกว่าผู้ใช้จะเลือกตำแหน่งใหม่ของวิดีโอ หากจำเป็นต้องบัฟเฟอร์ล่วงหน้า
เป็นเวลานานขึ้นขณะกรอ โปรดทำดังนี้
- จัดสรรบัฟเฟอร์การกรอก่อนเวลาและนำกลับมาใช้ใหม่
- ขนาดบัฟเฟอร์ควรมีขนาดไม่เกิน 15-25 MB (ขึ้นอยู่กับหน่วยความจำของอุปกรณ์)
- ระบุขนาดตัวแปรสำหรับบัฟเฟอร์สื่อโดยขึ้นอยู่กับ RAM ของอุปกรณ์และความละเอียดในการเล่นวิดีโอ ซึ่งควรคิดเป็นเวลา 1 นาที
ของการเล่นวิดีโอ ดังนี้
- การจัดสรร
- ใช้คำแนะนำเกี่ยวกับหน่วยความจำกราฟิกเพื่อให้แน่ใจว่า
คุณจะไม่ทำซ้ำรูปภาพในหน่วยความจำแบบไม่ระบุตัวตน
- รูปภาพมักเป็นสิ่งที่ใช้หน่วยความจำมากที่สุด ดังนั้นการทำซ้ำรูปภาพ อาจทำให้อุปกรณ์ทำงานหนักมาก โดยเฉพาะอย่างยิ่ง ในระหว่างการไปยังส่วนต่างๆ ของกริดวิวรูปภาพ
- ปล่อยการจัดสรรโดยการวางการอ้างอิงเมื่อย้าย หน้าจอ ตรวจสอบว่าไม่มีการอ้างอิงถึงบิตแมปและออบเจ็กต์ที่เหลืออยู่
- ใช้คำแนะนำเกี่ยวกับหน่วยความจำกราฟิกเพื่อให้แน่ใจว่า
คุณจะไม่ทำซ้ำรูปภาพในหน่วยความจำแบบไม่ระบุตัวตน
- ห้องสมุด:
- การจัดสรรหน่วยความจำของโปรไฟล์จากไลบรารีเมื่อเพิ่มโปรไฟล์ใหม่ เนื่องจาก อาจโหลดไลบรารีเพิ่มเติมด้วย ซึ่งอาจทำให้มีการจัดสรรและสร้างการเชื่อมโยงด้วย
- เครือข่าย:
- อย่าทำการเรียกเครือข่ายที่บล็อกระหว่างการเริ่มต้นแอป เพราะจะทำให้เวลาเริ่มต้นแอปพลิเคชันช้าลงและสร้างค่าใช้จ่ายเพิ่มเติมในหน่วยความจำ เมื่อเปิดตัว ซึ่งหน่วยความจำจะถูกจำกัดโดยการโหลดแอปเป็นพิเศษ แสดงหน้าจอที่ขึ้นว่ากำลังโหลดหรือหน้าจอ Splash ก่อน แล้วส่งคำขอเครือข่ายเมื่อ UI พร้อมใช้งาน
การเชื่อมโยง
การเชื่อมโยง ทำให้เกิดค่าใช้จ่ายเพิ่มเติมด้านหน่วยความจำเนื่องจากนำแอปพลิเคชันอื่นๆ เข้าสู่หน่วยความจำหรือเพิ่มการใช้หน่วยความจำของแอปที่เชื่อมโยง (หากอยู่ในหน่วยความจำอยู่แล้ว) เพื่ออำนวยความสะดวกในการเรียก API ซึ่งส่งผลให้ลดหน่วยความจำที่พร้อมใช้งานสำหรับแอปที่ทำงานอยู่เบื้องหน้า เมื่อเชื่อมโยงบริการ โปรดคำนึงถึงเวลาและระยะเวลาที่คุณใช้การเชื่อมโยง อย่าลืมยกเลิกการเชื่อมโยงทันทีที่ไม่ได้ใช้
การเชื่อมโยงทั่วไปและแนวทางปฏิบัติแนะนำ
- Play Integrity API: ใช้เพื่อตรวจสอบความสมบูรณ์ของอุปกรณ์
- ตรวจสอบความสมบูรณ์ของอุปกรณ์หลังจากหน้าจอการโหลดและก่อนการเล่นสื่อ
- ส่งการอ้างอิงถึง PlayIntegrity
StandardIntegrityManagerก่อนเล่นเนื้อหา
- Play Billing Library: ใช้เพื่อจัดการ
การสมัครใช้บริการและการซื้อโดยใช้ Google Play
- เริ่มต้นไลบรารีหลังจากหน้าจอการโหลด และจัดการงานการเรียกเก็บเงินทั้งหมดก่อนเล่นสื่อ
- ใช้
BillingClient.endConnection()เมื่อใช้ไลบรารีเสร็จแล้วและก่อนเล่นวิดีโอหรือสื่อเสมอ - ใช้
BillingClient.isReady()และBillingClient.getConnectionState()เพื่อตรวจสอบว่าระบบยกเลิกการเชื่อมต่อบริการหรือไม่ ในกรณีที่ต้องดำเนินการเรียกเก็บเงินอีกครั้ง จากนั้นให้ทำBillingClient.endConnection()อีกครั้งหลังจากเสร็จสิ้น
- GMS FontsProvider
- ควรใช้แบบอักษรแบบสแตนด์อโลนในอุปกรณ์ที่มี RAM ต่ำแทนการใช้ ผู้ให้บริการแบบอักษร เนื่องจากค่าใช้จ่ายในการดาวน์โหลดแบบอักษรสูง และ FontsProvider จะ เชื่อมโยงบริการเพื่อดำเนินการดังกล่าว
- ไลบรารี Google Assistant: บางครั้งใช้สำหรับการค้นหาและการค้นหาในแอป หากเป็นไปได้ ให้แทนที่ไลบรารีนี้
- สำหรับแอป Leanback: ใช้ข้อความพูดของ Gboard หรือไลบรารี
androidx.leanback
- ปฏิบัติตามหลักเกณฑ์ของ Search เพื่อใช้การค้นหา
- หมายเหตุ: เลิกใช้งาน Leanback แล้ว และแอปควรย้ายไปใช้ TV Compose
- สำหรับแอป Compose
- ใช้ข้อความพูดของ Gboard เพื่อใช้การค้นหาด้วยเสียง
- ใช้ดูต่อเพื่อให้ผู้ใช้ค้นพบเนื้อหาสื่อในแอปของคุณ
- สำหรับแอป Leanback: ใช้ข้อความพูดของ Gboard หรือไลบรารี
androidx.leanback
บริการที่ทำงานอยู่เบื้องหน้า
บริการที่ทำงานอยู่เบื้องหน้าเป็นบริการประเภทพิเศษที่เชื่อมโยงกับการแจ้งเตือน การแจ้งเตือนนี้จะ แสดงในถาดการแจ้งเตือนบนโทรศัพท์และแท็บเล็ต แต่อุปกรณ์ทีวีไม่มี ถาดการแจ้งเตือนในลักษณะเดียวกับอุปกรณ์เหล่านั้น แม้ว่าบริการที่ทำงานอยู่เบื้องหน้าจะมีประโยชน์เนื่องจากสามารถทำงานต่อไปได้ในขณะที่แอปพลิเคชันทำงานอยู่เบื้องหลัง แต่แอปทีวีต้องเป็นไปตามหลักเกณฑ์ต่อไปนี้
ใน Android TV และ Google TV จะอนุญาตให้บริการที่ทำงานอยู่เบื้องหน้าทำงานต่อไปได้เฉพาะในกรณีต่อไปนี้ เมื่อผู้ใช้ออกจากแอป
- สำหรับแอปเสียง อนุญาตให้บริการที่ทำงานอยู่เบื้องหน้าทำงานต่อไปได้เมื่อผู้ใช้ออกจาก แอปเพื่อเล่นแทร็กเสียงต่อไปเท่านั้น ต้องหยุดบริการทันที หลังจากที่การเล่นเสียงสิ้นสุดลง
- สำหรับแอปอื่นๆ: ต้องหยุดบริการที่ทำงานอยู่เบื้องหน้าทั้งหมด เมื่อผู้ใช้ออกจากแอป เนื่องจากไม่มีการแจ้งเตือนเพื่อแจ้งให้ผู้ใช้ทราบว่าแอปยังทำงานอยู่และใช้ทรัพยากร
- สำหรับงานในเบื้องหลัง เช่น การอัปเดตคำแนะนำหรือวิดีโอแนะนำให้รับชมถัดไป ให้ใช้
WorkManager
งานและการปลุก
WorkManager
เป็น Android API ที่ทันสมัยที่สุดสำหรับการกำหนดเวลางานที่เกิดซ้ำในเบื้องหลัง
WorkManager จะใช้ JobScheduler ใหม่เมื่อพร้อมใช้งาน (SDK
23 ขึ้นไป) และ AlarmManager เดิมเมื่อไม่พร้อมใช้งาน หากต้องการแนวทางปฏิบัติแนะนำในการเรียกใช้ชื่องานที่กำหนดเวลาไว้บนทีวี โปรดทำตามคำแนะนำต่อไปนี้
- หลีกเลี่ยงการใช้ API
AlarmManagerใน SDK 23 ขึ้นไป โดยเฉพาะAlarmManager.set()AlarmManager.setExact()และวิธีการที่คล้ายกัน เนื่องจาก API เหล่านี้ ไม่อนุญาตให้ระบบตัดสินใจเวลาที่เหมาะสมในการเรียกใช้ งาน (เช่น เมื่อ อุปกรณ์ไม่ได้ใช้งาน) - ในอุปกรณ์ที่มี RAM น้อย ให้หลีกเลี่ยงการเรียกใช้งานเว้นแต่จะจำเป็นจริงๆ หากจำเป็น ให้ใช้ WorkManager
WorkRequestเพื่ออัปเดตคำแนะนำหลังการเล่นเท่านั้น และพยายามดำเนินการขณะที่แอปยังเปิดอยู่ กำหนด WorkManager
Constraintsเพื่อให้ระบบเรียกใช้ งานของคุณเมื่อถึงเวลาที่เหมาะสม
Kotlin
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.setRequiresDeviceIdle(true)
.build()
Java
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.setRequiresDeviceIdle(true)
.build()
- หากคุณต้องเรียกใช้ Job เป็นประจำ (เช่น เพื่ออัปเดตวิดีโอถัดไปตามกิจกรรมการดูเนื้อหาของผู้ใช้ในแอปบนอุปกรณ์อื่น) ให้ลดการใช้หน่วยความจำโดยให้การใช้หน่วยความจำของ Job ต่ำกว่า 30 MB
ข้อควรพิจารณาทั่วไปเกี่ยวกับหน่วยความจำ
หลักเกณฑ์ต่อไปนี้ให้ข้อมูลทั่วไปเกี่ยวกับการพัฒนาแอป Android
- ลดการจัดสรรออบเจ็กต์ เพิ่มประสิทธิภาพการใช้ออบเจ็กต์ซ้ำ และยกเลิกการจัดสรรออบเจ็กต์ที่ไม่ได้ใช้ทันที
- อย่าเก็บการอ้างอิงไปยังออบเจ็กต์ โดยเฉพาะบิตแมป
- หลีกเลี่ยงการใช้
System.gc()และการเรียกใช้หน่วยความจำโดยตรง เนื่องจากจะรบกวนกระบวนการจัดการหน่วยความจำของระบบ เช่น ในอุปกรณ์ที่ใช้ zRAM การเรียกใช้gc()โดยบังคับอาจเพิ่มการใช้งานหน่วยความจำชั่วคราวเนื่องจากการบีบอัดและคลายการบีบอัดหน่วยความจำ - ใช้
LazyListเช่นที่แสดงใน เบราว์เซอร์แคตตาล็อกใน Compose หรือRecyclerViewใน ชุดเครื่องมือ UI ของ Leanback ที่เลิกใช้งานแล้วในตอนนี้ เพื่อนำมุมมองกลับมาใช้ใหม่และไม่ต้องสร้าง องค์ประกอบรายการใหม่ - แคชองค์ประกอบที่อ่านจากผู้ให้บริการเนื้อหาภายนอกซึ่งไม่น่าจะมีการเปลี่ยนแปลงไว้ในเครื่อง และกำหนดช่วงเวลาการอัปเดตเพื่อป้องกันไม่ให้มีการจัดสรรหน่วยความจำภายนอกเพิ่มเติม
- ตรวจสอบการรั่วไหลของหน่วยความจำที่อาจเกิดขึ้น
- ระวังกรณีหน่วยความจำรั่วไหลทั่วไป เช่น การอ้างอิงภายในเทรดที่ไม่ระบุตัวตน การจัดสรรบัฟเฟอร์วิดีโอใหม่ซึ่งไม่เคยได้รับการปล่อย และสถานการณ์อื่นๆ ที่คล้ายกัน
- ใช้ฮีปดัมป์เพื่อ แก้ไขข้อบกพร่องของหน่วยความจำรั่วไหล
- สร้างโปรไฟล์พื้นฐาน เพื่อลดปริมาณการคอมไพล์แบบทันทีที่จำเป็นเมื่อเรียกใช้ แอปใน Cold Start
ทำความเข้าใจการเรียกคืนหน่วยความจำโดยตรง
เมื่อแอปพลิเคชัน Android TV ขอหน่วยความจำและระบบทำงานหนัก เคอร์เนล Linux ซึ่งเป็นพื้นฐานของ Android อาจต้องใช้การเรียกคืนหน่วยความจำโดยตรง
กระบวนการนี้เกี่ยวข้องกับการหยุดเทรดการจัดสรรทั้งหมดชั่วคราวเพื่อรอ หน้าหน่วยความจำที่ว่าง ปัญหานี้เกิดขึ้นเมื่อการเรียกคืนหน่วยความจำเบื้องหลังไม่สามารถ รักษาพูลหน่วยความจำที่เพียงพอได้
ซึ่งอาจส่งผลให้เกิดการหยุดชั่วคราวหรือการกระตุกที่สังเกตเห็นได้ในประสบการณ์ของผู้ใช้ เนื่องจากระบบจะหยุดการจัดสรรเทรดจนกว่าจะมีหน่วยความจำเพียงพอ ใน แง่นี้ การจัดสรรเทรดไม่ได้จำกัดอยู่แค่การเรียกโค้ดของแอปพลิเคชัน เช่น malloc() แต่ต้องจัดสรรหน่วยความจำให้กับหน้าในหน้าโค้ดด้วย เช่น
สรุปเครื่องมือ
- ใช้เครื่องมือ โปรไฟล์หน่วยความจำของ Android Studio
เพื่อตรวจสอบการใช้หน่วยความจำขณะใช้งาน
- ใช้ heapdump เพื่อ ตรวจสอบการจัดสรรออบเจ็กต์และบิตแมปที่เฉพาะเจาะจง
- ใช้โปรไฟล์หน่วยความจำแบบเนทีฟ เพื่อตรวจสอบการจัดสรรที่ไม่ใช่ Java หรือ Kotlin
- ใช้ Android GPU Inspector เพื่อตรวจสอบการจัดสรรกราฟิก