ViewCapture là một công cụ phần mềm ghi lại các thuộc tính của khung hiển thị (chẳng hạn như vị trí, kích thước, tỷ lệ và chế độ hiển thị) được đính kèm vào các cửa sổ mà công cụ này được liên kết. ViewCapture ghi lại thông tin về nhiều khung hiển thị trong một cửa sổ và các thuộc tính của chúng, cho phép bạn biết trạng thái trải nghiệm người dùng tại những thời điểm cụ thể và theo dõi các thay đổi theo thời gian.
Bản ghi màn hình có thể trực quan hoá trạng thái của một khung hiển thị tại một thời điểm cụ thể và cho biết cách trạng thái đó thay đổi, nhưng chúng đòi hỏi tài nguyên CPU đáng kể và có thể ảnh hưởng đến hiệu suất. Công cụ ViewCapture ít ảnh hưởng đến tài nguyên và có thể được bật thường xuyên hơn. Ngoài ra, ViewCapture hiển thị hình ảnh trực quan theo từng khung hình ở cấp độ khung hiển thị, giúp bạn dễ dàng kiểm tra trạng thái khung hiển thị tại những thời điểm cụ thể hơn so với bản ghi màn hình.
Trang này mô tả cách tích hợp ViewCapture trong các ứng dụng hệ thống.
Mục đích sử dụng
ViewCapture.java triển khai một phiên bản của onDrawListener và thu thập dấu vết ViewCapture trong quá trình vẽ. Mỗi lần vẽ lại khung hình sẽ kích hoạt một lượt truyền tải hệ phân cấp cây chế độ xem, bắt đầu từ chế độ xem gốc của cửa sổ.
ViewCapture sử dụng các phương thức getter View.java công khai để tìm nạp và sao chép các giá trị vào một luồng nền nhằm cải thiện hiệu suất. Việc triển khai ViewCapture sẽ tối ưu hoá quy trình này bằng cách kiểm tra xem một khung hiển thị có bị bẩn hoặc không hợp lệ hay không bằng cách sử dụng captureViewTree, do đó tránh được việc duyệt qua toàn bộ hệ phân cấp khung hiển thị. captureViewTree chỉ dành cho các ứng dụng hệ thống và là một phần của UnsupportedAppUsage API.
Việc sử dụng API này chỉ giới hạn ở những ứng dụng dựa trên phiên bản SDK mục tiêu.
Các điểm hạn chế
Phần này mô tả các giới hạn về hiệu suất và bộ nhớ của ViewCapture.
Hiệu suất
Mức hao tổn trung bình của luồng chính đối với hiệu suất ViewCapture là 195 μs. Tuy nhiên, trong trường hợp xấu nhất, có thể mất khoảng 5 mili giây. Hãy tham khảo lát vc#onDraw trong dấu vết Perfetto.
Chi phí phát sinh chủ yếu là do những hành động sau:
- Việc truyền tải hệ phân cấp tiêu tốn 50 μs, ngay cả khi được cắt bớt.
- Việc kéo các đối tượng từ trình phân bổ danh sách tự do để lưu trữ bản sao của các thuộc tính chế độ xem sẽ tốn 20 μs.
- Việc tìm nạp từng giá trị thuộc tính thông qua một hàm getter sẽ dẫn đến nhiều lệnh gọi hàm bổ sung cho mỗi khung hiển thị, tốn 110 μs.
Do đó, việc bật ViewCapture trong tính năng theo dõi luôn bật (AOT) sẽ ảnh hưởng tiêu cực đến hiệu suất hệ thống và dẫn đến hiện tượng giật. Do những hạn chế về hiệu suất và bộ nhớ này, phương pháp này chưa sẵn sàng cho AOT. Bạn chỉ nên dùng ViewCapture cho việc gỡ lỗi cục bộ và trong phòng thí nghiệm.
Bộ nhớ
Phương thức của Perfetto cho dấu vết ViewCapture sử dụng một bộ đệm vòng duy nhất với dấu vết bộ nhớ được xác định trước để ngăn việc sử dụng quá nhiều bộ nhớ. Phương pháp này ngăn mức tiêu thụ bộ nhớ quá mức bằng cách tránh các bộ đệm vòng riêng biệt cho từng cửa sổ. Tuy nhiên, giải pháp này không giải quyết được vấn đề lưu trữ toàn bộ hệ phân cấp khung hiển thị cho mọi trạng thái trong Perfetto cho mỗi khung hình. Việc ghi lại một cửa sổ duy nhất, chẳng hạn như NexusLauncher, có thể tạo ra hơn 30 giây dữ liệu ViewCapture trong bộ đệm 10 MB. Để ghi lại hơn 30 cửa sổ từ Giao diện người dùng hệ thống, bạn cần có bộ đệm lớn hơn hoặc thời gian ghi hình ngắn hơn đáng kể.
Hướng dẫn
Để tích hợp ViewCapture vào các ứng dụng hệ thống, hãy làm theo hướng dẫn sau:
Thêm phần phụ thuộc vào tệp
Android.bp, như trong mã Trình chạy.android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }Tạo một thực thể ViewCapture khi tạo cửa sổ, ví dụ:
-
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"); } ... }
-
Đóng phiên bản ViewCapture khi huỷ cửa sổ, như minh hoạ trong các ví dụ sau: