Phát hiện giao diện người dùng bị giật

Android kết xuất giao diện người dùng bằng cách tạo một khung từ ứng dụng và hiển thị khung đó trên màn hình. Nếu ứng dụng của bạn kết xuất hình ảnh trên giao diện người dùng với tốc độ chậm thì hệ thống buộc phải bỏ qua một số khung. Khi vấn đề này xảy ra, người dùng sẽ thấy hiện tượng chập chờn lặp lại trên màn hình, hay còn gọi là hiện tượng giật (jank).

Hiện tượng giật xảy ra thường là do một số lệnh gọi bị giảm tốc hoặc chặn lệnh gọi không đồng bộ trên luồng giao diện người dùng (đây là luồng chính trong hầu hết các ứng dụng). Bạn có thể sử dụng tính năng theo dõi hệ thống để xác định vị trí xảy ra sự cố.

Nhận biết hiện tượng giật trên Android 12 trở lên

Đối với các thiết bị chạy Android 12 (API cấp 31) trở lên, một dấu vết được lưu lại sẽ hiển thị trong bảng theo dõi Khung hình bị giật bên trong ngăn Hiển thị của Trình phân tích CPU.

Để phát hiện tượng giật,

  1. Trong Android Studio, chọn View > Tool Windows > Profiler (Chế độ xem > Cửa sổ công cụ > Trình phân tích tài nguyên) hoặc nhấp vào Profile (Hồ sơ) trên thanh công cụ.

    Nếu hộp thoại Select Deployment Target (Chọn đối tượng triển khai) cho thấy lời nhắc, hãy chọn thiết bị nơi bạn muốn triển khai ứng dụng để phân tích. Nếu bạn đã kết nối thiết bị qua USB nhưng không thấy thiết bị đó trong danh sách, hãy đảm bảo rằng bạn đã bật tính năng gỡ lỗi USB.

  2. Nhấp vào bất kỳ nơi nào trong tiến trình CPU để mở Trình phân tích CPU (CPU Profiler).

  3. Chọn System Trace (Theo dõi hệ thống) từ trình đơn cấu hình trong Trình phân tích CPU, sau đó nhấp vào Ghi lại. Sau khi hoàn tất tương tác với ứng dụng của mình, bạn hãy nhấp vào Stop (Dừng).

  4. Bạn sẽ thấy thành phần Khung hình bị giật trong Hiển thị. Theo mặc định, Trình phân tích tài nguyên chỉ hiển thị các khung hình bị giật dưới dạng mục tiêu để điều tra. Trong mỗi khung hình bị giật, phần được tô màu đỏ sẽ làm nổi bật thời lượng khung hình vượt quá thời hạn kết xuất.Ảnh chụp màn hình của bảng theo dõi khung hình bị giật

  5. Khi phát hiện ra một khung hình bị giật, bạn hãy nhấp vào nó; bạn cũng có thể nhấn M để điều chỉnh mức thu phóng nhằm lấy nét tiêu điểm vào khung đã chọn. Các sự kiện có liên quan được đánh dấu trong các luồng này: luồng chính, RenderingThreadGPUcomplete. Ảnh chụp màn hình Trình phân tích tài nguyên hiển thị các Khung hình bị giật và chuỗi chính

  6. Bạn có thể tùy ý xem tất cả khung hình hoặc phân tích thời gian kết xuất bằng cách chọn/không chọn các hộp đánh dấu Tất cả các khungVòng đời tương ứng.Ảnh chụp màn hình của Trình phân tích tài nguyên như trên, nhưng hộp đánh dấu Tất cả khung hình và Vòng đời phải được chọn

Nhận biết hiện tượng giật trên Android 11

Đối với các thiết bị sử dụng Android 11 (API cấp 30), một dấu vết được lưu lại sẽ hiển thị ở mục Vòng đời khung hình trong Trình phân tích CPU.

Mục Vòng đời khung hình chứa nhiều bảng theo dõi khác nhau

Mục Vòng đời khung hình chứa tên lớp và 4 bảng theo dõi. Mỗi bảng theo dõi đại diện cho một giai đoạn trong quy trình kết xuất khung hình. Các phần tử Vòng đời khung hình bao gồm:

  1. Vòng đời khung hình (Tên lớp): Tiêu đề của mục chứa tên lớp trong dấu ngoặc đơn. Lớp (layer) là một thành phần kết hợp riêng lẻ.
  2. Application (Ứng dụng): Kênh này cho biết thời gian từ khi ứng dụng đưa vùng đệm ra khỏi hàng chờ đến khi vùng đệm đó được đưa lại vào hàng chờ. Thành phần này thường ứng với các sự kiện theo dõi trong RenderThread.
  3. Wait for GPU (Chờ GPU): Kênh này cho biết thời gian vùng đệm mà GPU chiếm dụng. Đây là thời gian kể từ khi vùng đệm được gửi đến GPU đến lúc GPU kết thúc hoạt động trên vùng đệm đó. Điều này không chứng minh GPU chỉ hoạt động duy nhất trên bộ đệm này trong suốt thời gian tải xuống. Để biết thông tin chi tiết về cách hoạt động của GPU trong một khoảng thời gian nhất định, bạn nên sử dụng Trình kiểm tra GPU Android.
  4. Composition (Thành phần): phần này hiển thị thời gian kể từ thời điểm SurfaceFlinger kết nối với vùng đệm đồng thời chuyển tới thành phần, cho đến khi vùng đệm được gửi đến màn hình hiển thị.
  5. Frames on display (Khung trên màn hình): phần này cho biết thời lượng khung hình hiển thị trên màn hình.

Mục Vòng đời khung hình minh họa cách vùng đệm khung di chuyển giữa các giai đoạn khác nhau của quá trình kết xuất hình ảnh hiển thị. Các khung này được mã hoá màu theo số khung để bạn có thể dễ dàng theo dõi một khung hình cụ thể.

Android Studio cũng hiển thị tất cả các khung hình trong bảng theo dõi ở định dạng bảng trong thẻ All Frames (Tất cả các khung).

Bảng liệt kê tất cả các khung hình trong bảng theo dõi ở thẻ All Frames (Tất cả các khung).

Khung #, Application (Ứng dụng), Chờ GPU và cột Composition thể hiện cùng dữ liệu với bảng theo dõi trong mục Vòng đời khung hình như trên. Cột Frame Duration (Thời lượng khung hình) thể hiện thời gian từ lúc khởi động Application (Ứng dụng) đến lúc Frames on Display (Khung trên màn hình) bắt đầu. Về cơ bản, các giá trị này thể hiện thời lượng để kết xuất một khung hình từ đầu đến cuối.

Bạn có thể sắp xếp bảng khung theo bất kỳ cột nào để tìm nhanh khung hình ngắn nhất hoặc dài nhất. Bảng cũng hỗ trợ các chế độ phân trang giúp bạn di chuyển qua hàng trăm khung hình.

Để phát hiện và điều tra hiện tượng giật xảy ra trên Android 11, hãy làm theo các bước sau:

  1. Sắp xếp bảng All Frames (Tất cả khung hình) theo cột Application (Ứng dụng) theo thứ tự giảm dần để các khung cần nhiều thời gian kết xuất nhất sẽ hiển thị trước.

    Cột Application (Ứng dụng) được sắp xếp theo thứ tự giảm dần

  2. Tìm các khung mất nhiều thời gian chạy nhất và chọn hàng trong bảng. Thao tác này sẽ phóng to khung đã chọn trong chế độ xem theo dòng thời gian ở bên trái.

    Chế độ xem theo dòng thời gian cùng với bảng Khung

  3. Tìm các luồng liên quan trong các mục Frame Lifecycle (Vòng đời khung hình) và Threads (Luồng).

    Các mục Vòng đời và Luồng

Nhận biết hiện tượng giật trên Android 10 trở xuống

Đối với các thiết bị sử dụng Android 10 (API cấp 29) trở xuống, thông tin về hệ thống đồ họa của hệ điều hành liên quan sẽ hiển thị trong một mục duy nhất trên bảng theo dõi hệ thống của Trình phân tích CPU có tên là Display (Hiển thị).

Cửa sổ hiển thị giao diện người dùng

  • Frames (Khung): Mục này cung cấp thông tin về luồng giao diện người dùng và bảng theo dõi RenderThread trong ứng dụng. Những sự kiện dài hơn 16 mili giây được tô màu đỏ nhằm làm nổi bật khung hình có thể bị giật, do các khung này đã vượt quá thời hạn kết xuất hiển thị thông thường ở tốc độ 60 khung hình/giây (fps).
  • SurfaceFlinger: Phần này cho biết thời điểm SurfaceFlinger xử lý vùng đệm khung. SurfaceFlinger là một quy trình hệ thống chịu trách nhiệm chuyển phát các vùng đệm để hiển thị.
  • VSYNC: Phần này hiển thị VSYNC, một tín hiệu đồng bộ hoá quy trình hiển thị. Thành phần này sẽ hiển thị tín hiệu ứng dụng VSYNC, cho biết khi nào ứng dụng của bạn khởi động mất quá nhiều thời gian. Thông thường, vấn đề này xảy ra do luồng giao diện người dùng đang bận. Khi đó, màn hình hoạt động sẽ trở nên chập chờn đồng thời có độ trễ nhất định cho đến khi ảnh động hoặc thao tác cuộn hoàn tất. Do đó, VSYNC đặc biệt quan trọng đối với người dùng sử dụng các màn hình có tốc độ làm mới cao, vì quy trình làm mới này có thể xảy ra với tần suất nhiều hơn 60 lần/giây hoặc với tần suất không cố định.
  • BufferQueue: Phần này cho biết số lượng vùng đệm khung được đưa vào hàng đợi và đang chờ SurfaceFlinger chiếm dụng. Đối với các ứng dụng được triển khai cho các thiết bị chạy Android 9 (cấp độ API 28) trở lên, phần này cho biết số lượng vùng đệm của nền tảng ứng dụng BufferQueue (0, 1 hoặc2 ). BufferQueue có thể giúp bạn hiểu rõ trạng thái của các vùng đệm hình ảnh khi chúng di chuyển giữa các thành phần đồ họa Android. Ví dụ: Giá trị 2 nghĩa là ứng dụng lúc này sẽ được lưu ba lần vào vùng đệm, tăng thêm độ trễ đầu vào.

Mục Display (Hiển thị) cung cấp các tín hiệu hữu ích để nhận biết hiện tượng giật tiềm ẩn. Ví dụ: khi luồng giao diện người dùng hoặc RenderThread diễn ra trong thời gian lâu hơn 16 mili giây. Để điều tra chi tiết và chính xác về nguyên nhân gây ra sự cố, bạn có thể thăm dò mục Luồng để hiển thị các luồng có liên quan đến quá trình kết xuất giao diện người dùng.

Mục Threads (Luồng) trong cửa sổ Display (Hiển thị)

Ở hình trên, mục Threads (Luồng) thể hiện luồng giao diện người dùng (java.com.google.samples.apps.iosched), RenderThread và luồng GPU completion. Đây là những luồng liên quan đến quá trình kết xuất giao diện người dùng có thể là nguyên nhân gây ra hiện tượng giật.

Để phát hiện tượng giật trên Android 10 trở xuống, hãy làm theo các bước sau:

  1. Xem phần Frames (Khung) trong cửa sổ Display (Hiển thị). Các khung màu đỏ là những đề xuất cho quá trình điều tra.

    Mục Frames (Khung) trong cửa sổ Display (Hiển thị)

  2. Khi bạn thấy một khung hình có khả năng bị giật, hãy phóng to màn hình đó bằng cách nhấn W hoặc cuộn con lăn chuột trong khi vẫn giữ phím Control (hoặc Command đối với macOS). Tiếp tục phóng to cho đến khi bạn bắt đầu thấy rõ các sự kiện theo dõi trong luồng giao diện người dùng và RenderThread.

    Theo dõi các sự kiện trong luồng giao diện người dùng và RenderThread (luồng kết xuất)

    Ở hình trên, Choreographer#doFrame cho thấy thời điểm luồng giao diện người dùng gọi Choreographer để phối hợp ảnh động, bố cục chế độ xem, bản vẽ hình ảnh và các quy trình liên quan. DrawFrames cho thấy thời điểm RenderThread hình thành và đưa ra các lệnh vẽ thực tế cho GPU.

  3. Nếu thấy một sự kiện theo dõi dài bất thường, bạn hãy phóng to để tìm hiểu những nguyên nhân có thể dẫn đến quá trình kết xuất chậm. Hình trên cho thấy inflate trong luồng giao diện người dùng, có nghĩa là ứng dụng đang dành thời gian để tăng cường bố cục. Khi phóng to một trong những sự kiện inflate, bạn có thể biết chính xác thời gian của mỗi thành phần giao diện người dùng như minh họa bên dưới.

    Trình đơn hiển thị thời lượng chính xác của một thành phần giao diện người dùng

Tìm hiểu thêm

Để tìm hiểu thêm về cách giảm hiện tượng giật, hãy xem Các nguồn phổ biến gây giật.