ViewCapture เป็นเครื่องมือซอฟต์แวร์ที่บันทึกพร็อพเพอร์ตี้ของมุมมอง (เช่น ตำแหน่ง ขนาด สเกล และระดับการมองเห็น) ที่แนบมากับหน้าต่างที่เชื่อมต่ออยู่ ViewCapture จะบันทึกข้อมูลเกี่ยวกับมุมมองต่างๆ ภายในหน้าต่าง และพร็อพเพอร์ตี้ของมุมมองเหล่านั้น เพื่อให้คุณทราบสถานะของประสบการณ์ของผู้ใช้ ณ ช่วงเวลาที่เฉพาะเจาะจง และติดตามการเปลี่ยนแปลงเมื่อเวลาผ่านไป
การบันทึกหน้าจอจะแสดงภาพสถานะของมุมมอง ณ เวลาที่เฉพาะเจาะจงและแสดงให้เห็น การเปลี่ยนแปลง แต่ต้องใช้ทรัพยากร CPU จำนวนมากและอาจส่งผลต่อ ประสิทธิภาพ เครื่องมือ ViewCapture มีผลกระทบต่อทรัพยากรน้อยกว่าและเปิดใช้ได้บ่อยกว่า นอกจากนี้ ViewCapture ยังแสดงภาพเฟรมต่อเฟรมที่ระดับมุมมอง ทำให้ตรวจสอบสถานะมุมมองได้ง่ายขึ้นในบางช่วงเวลาเมื่อเทียบกับการบันทึกหน้าจอ
หน้านี้จะอธิบายวิธีเริ่มต้นใช้งาน ViewCapture ในแอปของระบบ
ใช้
ViewCapture.java ใช้อินสแตนซ์ของ onDrawListener และรวบรวมร่องรอย ViewCapture ในระหว่างกระบวนการวาด การวาดเฟรมแต่ละเฟรมใหม่จะทริกเกอร์
การข้ามลำดับชั้นของแผนผังมุมมองโดยเริ่มที่มุมมองรากของหน้าต่าง
ViewCapture ใช้View.java
เมธอด Getter สาธารณะเพื่อดึงและคัดลอกค่าไปยัง
เธรดเบื้องหลังเพื่อปรับปรุงประสิทธิภาพ การติดตั้งใช้งาน ViewCapture
จะเพิ่มประสิทธิภาพกระบวนการนี้โดยการตรวจสอบว่ามุมมองมีการเปลี่ยนแปลงหรือใช้ไม่ได้โดยใช้ captureViewTree
จึงหลีกเลี่ยงการข้ามลำดับชั้นของมุมมองทั้งหมด captureViewTree ใช้ได้เฉพาะกับแอปของระบบและเป็นส่วนหนึ่งของ UnsupportedAppUsage API
การใช้ API นี้จำกัดไว้สำหรับแอปตามเวอร์ชัน SDK เป้าหมาย
ข้อจำกัด
ส่วนนี้จะอธิบายข้อจำกัดด้านประสิทธิภาพและหน่วยความจำของ ViewCapture
ประสิทธิภาพ
ค่าใช้จ่ายของเทรดหลักโดยเฉลี่ยสำหรับประสิทธิภาพ ViewCapture คือ
195 μs อย่างไรก็ตาม ในกรณีที่เลวร้ายที่สุด อาจใช้เวลาประมาณ 5 มิลลิวินาที โปรดดูvc#onDrawสไลซ์ในร่องรอยของ Perfetto
ต้นทุนค่าใช้จ่ายในการดำเนินงานส่วนใหญ่เกิดจากการดำเนินการต่อไปนี้
- การไปยังลําดับชั้นมีค่าใช้จ่าย 50 ไมโครวินาที แม้ว่าจะมีการตัดแต่งก็ตาม
- การดึงออบเจ็กต์จากเครื่องมือจัดสรรรายการอิสระเพื่อจัดเก็บสำเนาของพร็อพเพอร์ตี้มุมมอง มีค่าใช้จ่าย 20 μs
- การดึงค่าพร็อพเพอร์ตี้แต่ละรายการผ่านฟังก์ชัน Getter จะทําให้เกิดการเรียกฟังก์ชันเพิ่มเติมจํานวนมากต่อมุมมอง ซึ่งมีค่าใช้จ่าย 110 μs
ดังนั้น การเปิดใช้ ViewCapture ในการติดตามแบบเปิดตลอดเวลา (AOT) จะส่งผลเสียต่อประสิทธิภาพของระบบ และทำให้เกิดอาการกระตุก เนื่องจากข้อจำกัดด้านประสิทธิภาพและหน่วยความจำเหล่านี้ แนวทางนี้จึงยังไม่พร้อมสำหรับ AOT เราขอแนะนำให้ใช้ ViewCapture สำหรับการแก้ไขข้อบกพร่องในห้องทดลองและในเครื่องเท่านั้น
หน่วยความจำ
วิธีการของ Perfetto สำหรับการติดตาม ViewCapture จะใช้บัฟเฟอร์แบบวงเดียวที่มี ร่องรอยหน่วยความจำที่กำหนดไว้ล่วงหน้าเพื่อป้องกันการใช้หน่วยความจำมากเกินไป วิธีนี้ ช่วยป้องกันการใช้หน่วยความจำมากเกินไปโดยการหลีกเลี่ยงการใช้บัฟเฟอร์แบบวงกลมแยกกันสำหรับแต่ละ หน้าต่าง อย่างไรก็ตาม วิธีนี้ไม่ได้แก้ปัญหาการจัดเก็บลำดับชั้นของมุมมองทั้งหมดสำหรับทุกสถานะใน Perfetto สำหรับแต่ละเฟรม การบันทึกหน้าต่างเดียว เช่น NexusLauncher อาจสร้างข้อมูล ViewCapture ได้นานกว่า 30 วินาที ในบัฟเฟอร์ขนาด 10 MB การบันทึกหน้าต่างมากกว่า 30 หน้าต่างจาก UI ของระบบต้องใช้ บัฟเฟอร์ที่ใหญ่ขึ้นหรือเวลาในการบันทึกที่สั้นลงอย่างมาก
วิธีการ
หากต้องการเริ่มต้นใช้งาน ViewCapture ในแอปของระบบ ให้ทำตามวิธีการต่อไปนี้
- เพิ่มทรัพยากร Dependency ลงในไฟล์ - Android.bpดังที่แสดงในโค้ด Launcher- android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
- สร้างอินสแตนซ์ ViewCapture เมื่อสร้างหน้าต่าง เช่น - 
private SafeCloseable mViewCapture; @Override protected void onCreate(Bundle savedInstanceState) { ... mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow()); }
- 
private SafeCloseable mViewCapture; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (enableViewCaptureTracing()) { mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext()) .startCapture(getRootView(), ".NotificationShadeWindowView"); } ... }
 
- 
- ปิดอินสแตนซ์ ViewCapture เมื่อทำลายหน้าต่าง ดังที่แสดงใน ตัวอย่างต่อไปนี้ - 
@Override public void onDestroy() { ... if (mViewCapture != null) mViewCapture.close(); }
- 
@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mViewCaptureCloseable != null) { mViewCaptureCloseable.close(); } ... }
 
- 
