ViewCapture เป็นเครื่องมือซอฟต์แวร์ที่จับภาพพร็อพเพอร์ตี้ของมุมมอง (เช่น ตำแหน่ง ขนาด สเกล และระดับการมองเห็น) ที่แนบมากับหน้าต่างที่เชื่อมต่ออยู่ ViewCapture จะจับภาพข้อมูลเกี่ยวกับมุมมองต่างๆ ภายในหน้าต่างและพร็อพเพอร์ตี้ของมุมมองเหล่านั้น เพื่อให้คุณทราบสถานะของประสบการณ์ของผู้ใช้ในบางช่วงเวลาและติดตามการเปลี่ยนแปลงเมื่อเวลาผ่านไป
การบันทึกหน้าจอสามารถแสดงภาพสถานะของมุมมองในเวลาที่เฉพาะเจาะจงและแสดงให้เห็นว่ามุมมองเปลี่ยนแปลงไปอย่างไร แต่ต้องใช้ทรัพยากร CPU จำนวนมากและอาจส่งผลต่อประสิทธิภาพ เครื่องมือ ViewCapture ใช้ทรัพยากรน้อยกว่าและเปิดใช้ได้บ่อยกว่า นอกจากนี้ ViewCapture ยังแสดงภาพเฟรมต่อเฟรมที่ระดับมุมมอง ซึ่งทำให้การตรวจสอบสถานะมุมมองในบางช่วงเวลาทำได้ง่ายกว่าการบันทึกหน้าจอ
หน้านี้อธิบายวิธีเริ่มต้นใช้งาน ViewCapture ในแอปของระบบ
ใช้
ViewCapture.java จะใช้ onDrawListener อินสแตนซ์และรวบรวมการติดตาม ViewCapture ระหว่างกระบวนการวาด การวาดเฟรมใหม่แต่ละเฟรมจะทริกเกอร์การข้ามผ่านลำดับชั้นของแผนผังมุมมองโดยเริ่มจากมุมมองรากของหน้าต่าง
ViewCapture ใช้เมธอด Getter สาธารณะ View.java
เพื่อดึงและคัดลอกค่าไปยัง
เทรดเบื้องหลังเพื่อปรับปรุงประสิทธิภาพ การใช้งาน ViewCapture
จะเพิ่มประสิทธิภาพกระบวนการนี้โดยการตรวจสอบว่ามุมมองมีการแก้ไขหรือถูกทำให้ไม่ถูกต้องโดยใช้ captureViewTree,
ซึ่งจะหลีกเลี่ยงการข้ามผ่านลำดับชั้นการแสดงผลทั้งหมด captureViewTree พร้อมใช้งานสำหรับแอปของระบบเท่านั้นและเป็นส่วนหนึ่งของ UnsupportedAppUsage API
การใช้ API นี้จำกัดไว้สำหรับแอปตามเวอร์ชัน SDK เป้าหมาย
ข้อจำกัด
ส่วนนี้อธิบายข้อจำกัดด้านประสิทธิภาพและหน่วยความจำของ ViewCapture
ประสิทธิภาพ
ค่าใช้จ่ายเฉลี่ยของเทรดหลักสำหรับประสิทธิภาพของ ViewCapture คือ 195 μs อย่างไรก็ตาม ในสถานการณ์ที่แย่ที่สุด อาจใช้เวลา
ประมาณ 5 มิลลิวินาที โปรดดู Slice vc#onDraw ในการติดตาม
Perfetto
ค่าใช้จ่ายส่วนใหญ่เกิดจากการดำเนินการต่อไปนี้
- การข้ามผ่านลำดับชั้นมีค่าใช้จ่าย 50 μs แม้ว่าจะมีการตัดแต่งแล้วก็ตาม
- การดึงออบเจ็กต์จากตัวจัดสรรรายการอิสระเพื่อจัดเก็บสำเนาพร็อพเพอร์ตี้ของมุมมองมีค่าใช้จ่าย 20 μs
- การดึงค่าพร็อพเพอร์ตี้แต่ละค่าผ่านฟังก์ชัน Getter จะส่งผลให้มีการเรียกฟังก์ชันเพิ่มเติมจำนวนมากต่อมุมมอง ซึ่งมีค่าใช้จ่าย 110 μs
ดังนั้น การเปิดใช้ ViewCapture ในการติดตามตลอดเวลา (AOT) จะส่งผลเสียต่อประสิทธิภาพของระบบและทำให้เกิดอาการกระตุก เนื่องจากข้อจำกัดด้านประสิทธิภาพและหน่วยความจำเหล่านี้ วิธีนี้จึงยังไม่พร้อมใช้งานสำหรับ AOT เราขอแนะนำให้ใช้ ViewCapture สำหรับการดีบักในห้องทดลองและในเครื่องเท่านั้น
หน่วยความจำ
เมธอดของการติดตาม ViewCapture ของ Perfetto ใช้บัฟเฟอร์แบบวงแหวนเดียวที่มีหน่วยความจำที่ใช้ที่กำหนดไว้ล่วงหน้าเพื่อป้องกันการใช้หน่วยความจำมากเกินไป วิธีนี้จะป้องกันการใช้หน่วยความจำมากเกินไปโดยหลีกเลี่ยงบัฟเฟอร์แบบวงแหวนแยกกันสำหรับแต่ละหน้าต่าง อย่างไรก็ตาม วิธีนี้ไม่ได้แก้ปัญหาการจัดเก็บลำดับชั้นของมุมมองทั้งหมดสำหรับทุกสถานะใน Perfetto สำหรับแต่ละเฟรม การบันทึกหน้าต่างเดียว เช่น NexusLauncher อาจสร้างข้อมูล ViewCapture ได้นานกว่า 30 วินาทีในบัฟเฟอร์ขนาด 10 MB การจับภาพหน้าต่างมากกว่า 30 หน้าต่างจาก UI ของระบบต้องใช้บัฟเฟอร์ที่ใหญ่ขึ้นหรือใช้เวลาบันทึกที่สั้นลงอย่างมาก
วิธีการ
หากต้องการเริ่มต้นใช้งาน ViewCapture ในแอปของระบบ ให้ทำตามวิธีการต่อไปนี้
เพิ่มทรัพยากร Dependency ลงในไฟล์
Android.bpดังที่แสดงใน โค้ด Launcherandroid_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(); } ... }
-