ViewCapture ในแอประบบ

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

ค่าใช้จ่ายส่วนใหญ่เกิดจากการดำเนินการต่อไปนี้

  1. การข้ามผ่านลำดับชั้นมีค่าใช้จ่าย 50 μs แม้ว่าจะมีการตัดแต่งแล้วก็ตาม
  2. การดึงออบเจ็กต์จากตัวจัดสรรรายการอิสระเพื่อจัดเก็บสำเนาพร็อพเพอร์ตี้ของมุมมองมีค่าใช้จ่าย 20 μs
  3. การดึงค่าพร็อพเพอร์ตี้แต่ละค่าผ่านฟังก์ชัน Getter จะส่งผลให้มีการเรียกฟังก์ชันเพิ่มเติมจำนวนมากต่อมุมมอง ซึ่งมีค่าใช้จ่าย 110 μs

ดังนั้น การเปิดใช้ ViewCapture ในการติดตามตลอดเวลา (AOT) จะส่งผลเสียต่อประสิทธิภาพของระบบและทำให้เกิดอาการกระตุก เนื่องจากข้อจำกัดด้านประสิทธิภาพและหน่วยความจำเหล่านี้ วิธีนี้จึงยังไม่พร้อมใช้งานสำหรับ AOT เราขอแนะนำให้ใช้ ViewCapture สำหรับการดีบักในห้องทดลองและในเครื่องเท่านั้น

หน่วยความจำ

เมธอดของการติดตาม ViewCapture ของ Perfetto ใช้บัฟเฟอร์แบบวงแหวนเดียวที่มีหน่วยความจำที่ใช้ที่กำหนดไว้ล่วงหน้าเพื่อป้องกันการใช้หน่วยความจำมากเกินไป วิธีนี้จะป้องกันการใช้หน่วยความจำมากเกินไปโดยหลีกเลี่ยงบัฟเฟอร์แบบวงแหวนแยกกันสำหรับแต่ละหน้าต่าง อย่างไรก็ตาม วิธีนี้ไม่ได้แก้ปัญหาการจัดเก็บลำดับชั้นของมุมมองทั้งหมดสำหรับทุกสถานะใน Perfetto สำหรับแต่ละเฟรม การบันทึกหน้าต่างเดียว เช่น NexusLauncher อาจสร้างข้อมูล ViewCapture ได้นานกว่า 30 วินาทีในบัฟเฟอร์ขนาด 10 MB การจับภาพหน้าต่างมากกว่า 30 หน้าต่างจาก UI ของระบบต้องใช้บัฟเฟอร์ที่ใหญ่ขึ้นหรือใช้เวลาบันทึกที่สั้นลงอย่างมาก

วิธีการ

หากต้องการเริ่มต้นใช้งาน ViewCapture ในแอปของระบบ ให้ทำตามวิธีการต่อไปนี้

  1. เพิ่มทรัพยากร Dependency ลงในไฟล์ Android.bp ดังที่แสดงใน โค้ด Launcher

    android_library {
        name: "YourLib",
        static_libs: [
              ...
            "//frameworks/libs/systemui:view_capture",
              ...
        ],
        platform_apis: true,
        privileged: true,
    }
    
  2. สร้างอินสแตนซ์ ViewCapture เมื่อสร้างหน้าต่าง เช่น

    • ตัวอย่างที่ 1:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
      }
      
    • ตัวอย่างที่ 2:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableViewCaptureTracing()) {
            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
              .startCapture(getRootView(), ".NotificationShadeWindowView");
        }
        ...
      }
      
  3. ปิดอินสแตนซ์ ViewCapture เมื่อทำลายหน้าต่าง ดังที่แสดงในตัวอย่างต่อไปนี้