Kể từ Android 3.0 (API cấp độ 11), quy trình kết xuất hình ảnh 2D của Android có hỗ trợ tăng tốc phần cứng, nghĩa là tất cả các thao tác vẽ được thực hiện trên canvas của View
đều sử dụng GPU. Do đã tăng tài nguyên cần thiết để bật tính năng tăng tốc phần cứng, nên ứng dụng sẽ tốn nhiều RAM hơn.
Tính năng tăng tốc phần cứng được bật theo mặc định nếu cấp độ API mục tiêu của bạn >=14 nhưng cũng có thể được bật theo cách rõ ràng. Nếu ứng dụng của bạn chỉ sử dụng các thành phần hiển thị chuẩn và Drawable
, thì việc bật tính năng này trên toàn cục sẽ không gây ra hiệu ứng bất lợi nào về mặt hình ảnh. Tuy nhiên, vì tính năng tăng tốc phần cứng không hỗ trợ toàn bộ thao tác vẽ 2D, nên việc bật tính năng này có thể ảnh hưởng đến một số thành phần hiển thị tuỳ chỉnh hoặc lệnh gọi vẽ. Sự cố sẽ xuất hiện dưới dạng các phần tử bị ẩn đi, ngoại lệ hoặc pixel kết xuất không chính xác. Để khắc phục điều này, Android cung cấp cho bạn tuỳ chọn bật hoặc tắt tính năng tăng tốc phần cứng ở nhiều cấp độ. Hãy xem phần Kiểm soát tính năng tăng tốc phần cứng.
Nếu ứng dụng của bạn có thực hiện thao tác vẽ tuỳ chỉnh, hãy kiểm thử ứng dụng đó trên các thiết bị phần cứng thực tế đã bật tính năng tăng tốc phần cứng để phát hiện mọi vấn đề. Phần Hỗ trợ cho hoạt động vẽ mô tả các vấn đề đã biết với tính năng tăng tốc phần cứng, cũng như cách khắc phục.
Ngoài ra, hãy xem bài viết Sử dụng OpenGL với các API Khung và Tập lệnh kết xuất
Kiểm soát tính năng tăng tốc phần cứng
Bạn có thể kiểm soát tính năng tăng tốc phần cứng ở các cấp độ sau:
- Application (Ứng dụng)
- Activity (Hoạt động)
- Window (Cửa sổ)
- View (Thành phần hiển thị)
Cấp độ ứng dụng
Trong tệp kê khai Android, hãy thêm thuộc tính sau vào thẻ
<application>
để bật tính năng tăng tốc phần cứng cho toàn bộ
ứng dụng:
<application android:hardwareAccelerated="true" ...>
Cấp độ hoạt động
Nếu tính năng tăng tốc phần cứng được bật trên toàn cục mà ứng dụng của bạn hoạt động không đúng cách, thì bạn cũng có thể kiểm soát tính năng này đối với các hoạt động riêng lẻ. Để bật hoặc tắt tính năng tăng tốc phần cứng ở cấp độ hoạt động, bạn có thể sử dụng thuộc tính android:hardwareAccelerated
cho phần tử <activity>
. Ở ví dụ sau đây, chúng ta sẽ bật tính năng tăng tốc phần cứng cho toàn bộ ứng dụng nhưng tắt tính năng này đối với một hoạt động:
<application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /> </application>
Cấp độ cửa sổ
Nếu cần kiểm soát chi tiết hơn nữa, bạn có thể bật tính năng tăng tốc phần cứng cho một cửa sổ cụ thể bằng mã sau:
Kotlin
window.setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED )
Java
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
Lưu ý: Bạn hiện không thể tắt tính năng tăng tốc phần cứng ở cấp độ cửa sổ.
Cấp độ thành phần hiển thị
Bạn có thể tắt tính năng tăng tốc phần cứng cho một thành phần hiển thị riêng lẻ trong thời gian chạy bằng mã sau:
Kotlin
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
Java
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Lưu ý: Bạn hiện không thể bật tính năng tăng tốc phần cứng ở cấp độ thành phần hiển thị. Ngoài việc tắt tính năng tăng tốc phần cứng, các lớp phủ thành phần hiển thị còn có những chức năng khác. Hãy xem phần Lớp phủ thành phần hiển thị để biết thêm thông tin về cách sử dụng các chức năng này.
Xác định xem một thành phần hiển thị có được tăng tốc phần cứng hay không
Đôi khi, việc biết được là một ứng dụng hiện có được tăng tốc phần cứng hay không sẽ hữu ích, đặc biệt là đối với những phần tử như thành phần hiển thị tuỳ chỉnh. Điều này đặc biệt hữu ích nếu ứng dụng có thực hiện nhiều thao tác vẽ tuỳ chỉnh và không phải tất cả thao tác đều được quy trình kết xuất mới hỗ trợ đúng cách.
Có hai cách để kiểm tra xem ứng dụng có được tăng tốc phần cứng hay không:
View.isHardwareAccelerated()
sẽ trả vềtrue
nếuView
được gắn với một cửa sổ được tăng tốc phần cứng.Canvas.isHardwareAccelerated()
sẽ trả vềtrue
nếuCanvas
được tăng tốc phần cứng
Nếu bạn phải thực hiện việc kiểm tra này trong mã lập trình thực hiện thao tác vẽ, hãy sử dụng Canvas.isHardwareAccelerated()
thay vì View.isHardwareAccelerated()
khi có thể. Khi một thành phần hiển thị được gắn với một cửa sổ đã tăng tốc phần cứng, thì bạn vẫn có thể vẽ thành phần hiển thị đó bằng Canvas không có tăng tốc phần cứng. Tình huống này xảy ra, chẳng hạn khi bạn vẽ một thành phần hiển thị vào bitmap cho mục đích lưu vào bộ nhớ đệm.
Mô hình vẽ của Android
Khi bật tính năng tăng tốc phần cứng, khung Android sẽ sử dụng một mô hình vẽ mới tận dụng danh sách hiển thị để kết xuất ứng dụng lên màn hình. Để hiểu đầy đủ về các danh sách hiển thị và mức độ ảnh hưởng của các danh sách này đến ứng dụng, bạn nên nắm được cách Android vẽ các thành phần hiển thị mà không cần tăng tốc phần cứng. Các phần sau mô tả về các mô hình vẽ dựa trên phần mềm và mô hình vẽ được tăng tốc phần cứng.
Mô hình vẽ dựa trên phần mềm
Trong mô hình vẽ dựa trên phần mềm, các thành phần hiển thị được vẽ theo 2 bước sau:
- Vô hiệu hoá hệ thống phân cấp
- Vẽ hệ thống phân cấp
Khi cần cập nhật một phần giao diện người dùng, ứng dụng sẽ gọi invalidate()
(hoặc một trong các biến thể của phương thức này) trên bất cứ thành phần hiển thị nào đã thay đổi nội dung. Thông báo vô hiệu hoá được truyền đi khắp hệ thống phân cấp thành phần hiển thị để tính toán các vùng màn hình cần vẽ lại (vùng bẩn). Sau đó, hệ thống Android sẽ vẽ mọi thành phần hiển thị trong hệ thống phân cấp có giao nhau với vùng bẩn. Đáng tiếc là có hai hạn chế đối với mô hình vẽ này:
- Trước tiên, mô hình này yêu cầu thực thi nhiều mã mỗi lần vẽ. Ví dụ: nếu ứng dụng gọi phương thức
invalidate()
trên một nút nhấn và nút đó nằm trên đầu một thành phần hiển thị khác, thì hệ thống Android sẽ vẽ lại thành phần hiển thị đó (mặc dù chưa thay đổi). - Vấn đề thứ hai là: mô hình vẽ có thể làm ẩn lỗi trong ứng dụng. Vì hệ thống Android vẽ lại các thành phần hiển thị khi có giao nhau với vùng bẩn, nên một thành phần hiển thị có nội dung đã được bạn thay đổi có thể được vẽ lại mặc dù
invalidate()
không được gọi trên đó. Khi điều này xảy ra, bạn sẽ dựa vào một thành phần hiển thị khác đang bị vô hiệu để có được hành vi phù hợp. Hành vi này có thể thay đổi mỗi khi bạn sửa đổi ứng dụng. Do đó, bạn phải luôn gọiinvalidate()
trên các thành phần hiển thị tuỳ chỉnh mỗi khi thực hiện việc sửa đổi dữ liệu hoặc trạng thái có ảnh hưởng đến mã lập trình vẽ của thành phần hiển thị đó.
Lưu ý: Các thành phần hiển thị của Android sẽ tự động gọi invalidate()
khi các thuộc tính thay đổi, chẳng hạn như màu nền hoặc văn bản trong TextView
.
Mô hình vẽ được tăng tốc phần cứng
Hệ thống Android vẫn sử dụng invalidate()
và draw()
để yêu cầu cập nhật màn hình và kết xuất các thành phần hiển thị, nhưng lại xử lý thao tác vẽ thực tế theo cách khác. Thay vì thực thi các lệnh vẽ ngay lập tức, hệ thống Android sẽ ghi lại các lệnh đó bên trong danh sách hiển thị (chứa đầu ra mã lập trình vẽ của hệ thống phân cấp thành phần hiển thị). Một phương pháp tối ưu hoá khác là hệ thống Android chỉ cần ghi lại và cập nhật danh sách hiển thị cho các thành phần hiển thị được đánh dấu là có sửa đổi bằng lệnh gọi invalidate()
. Bạn có thể vẽ lại các thành phần hiển thị chưa bị vô hiệu bằng cách phân phát lại danh sách hiển thị đã được ghi lại trước đó. Mô hình vẽ mới gồm 3 giai đoạn:
- Vô hiệu hoá hệ thống phân cấp
- Ghi và cập nhật danh sách hiển thị
- Vẽ danh sách hiển thị
Với mô hình này, bạn không thể dựa vào một thành phần hiển thị giao với vùng có sửa đổi để thực thi phương thức draw()
. Để đảm bảo rằng hệ thống Android ghi lại danh sách hiển thị của một thành phần hiển thị, bạn phải gọi phương thức invalidate()
. Nếu quên làm điều này, các thành phần hiển thị vẫn sẽ trông giống như cũ ngay cả khi bạn đã thay đổi thành phần hiển thị đó.
Việc sử dụng danh sách hiển thị cũng làm tăng hiệu suất ảnh động vì việc thiết lập các thuộc tính cụ thể (chẳng hạn như alpha hoặc góc xoay) không yêu cầu phải vô hiệu hoá thành phần hiển thị được nhắm mục tiêu (việc này được thực hiện tự động). Quá trình tối ưu hoá này cũng áp dụng cho các thành phần hiển thị có danh sách hiển thị (mọi thành phần hiển thị khi ứng dụng được tăng tốc phần cứng). Ví dụ: giả sử có một LinearLayout
chứa một ListView
phía trên một Button
. Danh sách hiển thị cho LinearLayout
có dạng như sau:
- DrawDisplayList(ListView)
- DrawDisplayList(Button)
Giả sử bây giờ bạn muốn thay đổi độ mờ của ListView
. Sau khi gọi setAlpha(0.5f)
trên ListView
, danh sách hiển thị sẽ chứa nội dung sau:
- SaveLayerAlpha(0.5)
- DrawDisplayList(ListView)
- Restore
- DrawDisplayList(Button)
Mã lập trình vẽ phức tạp của ListView
không được thực thi. Thay vào đó, hệ thống chỉ cập nhật danh sách hiển thị của LinearLayout
(đơn giản hơn). Trong một ứng dụng chưa bật tính năng tăng tốc phần cứng, mã lập trình vẽ của cả danh sách đó và phần tử mẹ của danh sách đó sẽ được thực thi lại.
Hỗ trợ các thao tác vẽ
Khi tăng tốc phần cứng, quy trình kết xuất hình ảnh 2D hỗ trợ các thao tác vẽ Canvas
phổ biến nhất cũng như các thao tác ít sử dụng hơn. Tất cả thao tác vẽ được dùng để kết xuất các ứng dụng xuất hiện trên Android, các tiện ích và bố cục mặc định cũng như các hiệu ứng hình ảnh nâng cao phổ biến như phản chiếu và hoạ tiết xếp kề đều được hỗ trợ.
Bảng sau đây mô tả mức độ hỗ trợ đối với các thao tác khác nhau theo các cấp độ API:
Cấp độ API đầu tiên được hỗ trợ | ||||
Canvas | ||||
drawBitmapMesh() (mảng màu) | 18 | |||
drawPicture() | 23 | |||
drawPosText() | 16 | |||
drawTextOnPath() | 16 | |||
drawVertices() | 29 | |||
setDrawFilter() | 16 | |||
clipPath() | 18 | |||
clipRegion() | 18 | |||
clipRect(Region.Op.XOR) | 18 | |||
clipRect(Region.Op.Difference) | 18 | |||
clipRect(Region.Op.ReverseDifference) | 18 | |||
clipRect() có chế độ xoay/góc nhìn | 18 | |||
Paint | ||||
setAntiAlias() (dành cho văn bản) | 18 | |||
setAntiAlias() (dành cho các đường thẳng) | 16 | |||
setFilterBitmap() | 17 | |||
setLinearText() | ✗ | |||
setMaskFilter() | ✗ | |||
setPathEffect() (dành cho các đường thẳng) | 28 | |||
setShadowLayer() (không dành cho văn bản) | 28 | |||
setStrokeCap() (dành cho các đường thẳng) | 18 | |||
setStrokeCap() (dành cho các điểm) | 19 | |||
setSubpixelText() | 28 | |||
Xfermode | ||||
PorterDuff.Mode.DARKEN (bộ đệm khung) | 28 | |||
PorterDuff.Mode.LIGHTEN (bộ đệm khung) | 28 | |||
PorterDuff.Mode.OVERLAY (bộ đệm khung) | 28 | |||
Trình đổ bóng | ||||
ComposeShader bên trong ComposeShader | 28 | |||
Các trình đổ bóng cùng kiểu bên trong ComposeShader | 28 | |||
Ma trận cục bộ trên ComposeShader | 18 |
Điều chỉnh tỷ lệ Canvas
Ban đầu, tính năng tăng tốc phần cứng được xây dựng để hỗ trợ quy trình kết xuất hình ảnh 2D đối với các thao tác vẽ chưa điều chỉnh tỷ lệ. Tuy nhiên, một số thao tác vẽ bị giảm chất lượng đáng kể ở những hệ số tỷ lệ cao hơn. Các thao tác này được triển khai bằng cách vẽ các hoạ tiết ở tỷ lệ 1.0, sau đó sẽ được GPU chuyển đổi. Kể từ API cấp 28, bạn có thể điều chỉnh tỷ lệ mọi thao tác vẽ mà không gặp vấn đề gì.
Bảng sau đây cho thấy thời điểm thay đổi quy trình triển khai để xử lý chính xác trên những hệ số tỷ lệ lớn:Thao tác vẽ được điều chỉnh theo tỷ lệ | Cấp độ API đầu tiên được hỗ trợ |
drawText() | 18 |
drawPosText() | 28 |
drawTextOnPath() | 28 |
Hình dạng đơn giản* | 17 |
Hình dạng phức tạp* | 28 |
drawPath() | 28 |
Lớp đổ bóng | 28 |
Lưu ý: Lệnh vẽ hình dạng "đơn giản" là drawRect()
, drawCircle()
, drawOval()
, drawRoundRect()
và drawArc()
(với useCenter=false) được phân phát với lệnh Paint không có PathEffect và không chứa các cách kết hợp không mặc định (thông qua setStrokeJoin()
/setStrokeMiter()
). Các trường hợp khác của những lệnh vẽ này nằm ở phần "Phức tạp", trong biểu đồ trên.
Nếu ứng dụng của bạn bị ảnh hưởng vì thiếu tính năng hoặc gặp phải hạn chế nào đó trong số này, bạn có thể tắt tính năng tăng tốc phần cứng riêng cho phần bị ảnh hưởng của ứng dụng bằng cách gọi setLayerType(View.LAYER_TYPE_SOFTWARE, null)
. Bằng cách này, bạn vẫn có thể tận dụng tính năng tăng tốc phần cứng ở những phần khác. Hãy xem phần Kiểm soát tính năng tăng tốc phần cứng để biết thêm thông tin về cách bật và tắt tính năng tăng tốc phần cứng ở các cấp độ trong ứng dụng.
Các lớp phủ thành phần hiển thị
Trong tất cả các phiên bản Android, các thành phần hiển thị đều có khả năng kết xuất vào vùng đệm ngoài màn hình, bằng cách sử dụng bộ nhớ đệm cho thao tác vẽ của thành phần hiển thị hoặc bằng cách sử dụng Canvas.saveLayer()
. Các vùng đệm hoặc lớp phủ ngoài màn hình có một số mục đích sử dụng. Bạn có thể sử dụng các thành phần này để đạt được hiệu suất tốt hơn khi tạo ảnh động phức tạp cho các thành phần hiển thị hoặc để áp dụng các hiệu ứng tổng hợp. Ví dụ: bạn có thể triển khai hiệu ứng làm mờ bằng cách sử dụng Canvas.saveLayer()
để tạm thời kết xuất thành phần hiển thị vào một lớp phủ rồi tổng hợp lại thành phần hiển thị đó trên màn hình với hệ số độ mờ.
Kể từ Android 3.0 (API cấp độ 11), bạn có thể kiểm soát tốt hơn về cách thức và thời điểm sử dụng các lớp phủ bằng phương thức View.setLayerType()
. API này nhận hai thông số: kiểu lớp phủ bạn muốn sử dụng và một đối tượng Paint
không bắt buộc mô tả cách tổng hợp lớp phủ đó. Bạn có thể sử dụng thông số Paint
để áp dụng bộ lọc màu, chế độ phối đặc biệt hoặc độ mờ cho một lớp phủ. Một thành phần hiển thị có thể sử dụng một trong ba kiểu lớp phủ:
LAYER_TYPE_NONE
: Thành phần hiển thị được kết xuất bình thường và không được hỗ trợ bởi vùng đệm ngoài màn hình. Đây là hành vi mặc định.LAYER_TYPE_HARDWARE
: Nếu ứng dụng được tăng tốc phần cứng, thành phần hiển thị đó sẽ được kết xuất trong phần cứng thành hoạ tiết phần cứng. Nếu ứng dụng không được tăng tốc phần cứng, thì kiểu lớp phủ này sẽ hoạt động giống nhưLAYER_TYPE_SOFTWARE
.LAYER_TYPE_SOFTWARE
: Thành phần hiển thị sẽ được kết xuất trong phần mềm thành một bitmap.
Kiểu lớp phủ bạn sử dụng sẽ tuỳ thuộc vào mục tiêu của bạn:
- Hiệu suất: Sử dụng kiểu lớp phủ phần cứng để kết xuất thành phần hiển thị thành hoạ tiết phần cứng. Sau khi một thành phần hiển thị được hiển thị vào một lớp phủ, mã vẽ của lớp phủ đó không cần phải được thực thi cho đến khi thành phần hiển thị này gọi
invalidate()
. Sau đó, một số ảnh động, chẳng hạn như ảnh động alpha, có thể được áp dụng trực tiếp vào lớp phủ. Việc này được GPU thực hiện rất hiệu quả. - Hiệu ứng hình ảnh: Sử dụng kiểu lớp phủ phần cứng hoặc phần mềm và
Paint
để áp dụng các biện pháp xử lý hình ảnh đặc biệt cho một thành phần hiển thị. Ví dụ: bạn có thể vẽ một thành phần hiển thị dạng đen trắng bằng cách sử dụngColorMatrixColorFilter
. - Khả năng tương thích: Sử dụng kiểu lớp phủ phần mềm để buộc kết xuất thành phần hiển thị trong phần mềm. Nếu một thành phần hiển thị được tăng tốc phần cứng (chẳng hạn trong trường hợp toàn bộ ứng dụng của bạn được tăng tốc phần cứng) gặp phải vấn đề về việc kết xuất hình ảnh, đây sẽ là một cách dễ dàng để giải quyết các giới hạn của quy trình kết xuất hình ảnh bằng phần cứng.
Lớp phủ thành phần hiển thị và ảnh động
Các lớp phủ phần cứng có thể phân phối ảnh động nhanh hơn và mượt mà hơn khi ứng dụng của bạn được tăng tốc phần cứng. Không phải lúc nào bạn cũng có thể chạy ảnh động ở tốc độ 60 khung hình/giây khi tạo ảnh động cho các thành phần hiển thị phức tạp đòi hỏi nhiều thao tác vẽ. Bạn có thể giảm bớt tình trạng này bằng cách sử dụng lớp phủ phần cứng để kết xuất thành phần hiển thị lên hoạ tiết phần cứng. Sau đó, hoạ tiết phần cứng có thể được dùng để tạo ảnh động cho thành phần hiển thị mà không cần phải vẽ lại mỗi khi hình ảnh chuyển động. Khung hiển thị sẽ không được vẽ lại trừ phi bạn thay đổi
để gọi invalidate()
hoặc nếu bạn gọi invalidate()
theo cách thủ công. Nếu bạn đang chạy ảnh động trong ứng dụng và không thu được kết quả mượt mà như mong muốn, hãy cân nhắc bật lớp phủ phần cứng trên các thành phần hiển thị có ảnh động.
Khi một thành phần hiển thị được lớp phủ phần cứng hỗ trợ, một số thuộc tính của lớp phủ đó được xử lý theo cách tổng hợp lớp phủ trên màn hình. Việc thiết lập các thuộc tính này sẽ hiệu quả vì không yêu cầu thành phần hiển thị bị vô hiệu hoá và vẽ lại. Danh sách các thuộc tính sau đây ảnh hưởng đến cách tổng hợp lớp phủ này. Việc gọi phương thức setter cho bất kỳ thuộc tính nào trong số các thuộc tính này sẽ dẫn đến việc vô hiệu tính năng tối ưu hoá và không vẽ lại thành phần hiển thị mục tiêu:
alpha
: Thay đổi độ mờ của lớp phủx
,y
,translationX
,translationY
: Thay đổi vị trí của lớp phủscaleX
,scaleY
: Thay đổi kích thước của lớp phủrotation
,rotationX
,rotationY
: Thay đổi hướng của lớp phủ trong không gian 3DpivotX
,pivotY
: Thay đổi nguồn gốc biến đổi của lớp phủ
Tên của các thuộc tính này cũng được dùng khi tạo ảnh động cho một thành phần hiển thị bằng ObjectAnimator
. Nếu bạn muốn truy cập các thuộc tính này, hãy gọi phương thức setter hoặc getter thích hợp. Ví dụ: để sửa đổi thuộc tính alpha, hãy gọi setAlpha()
. Đoạn mã sau đây trình bày cách hiệu quả nhất để xoay một thành phần hiển thị ở chế độ 3D quanh trục Y:
Kotlin
view.setLayerType(View.LAYER_TYPE_HARDWARE, null) ObjectAnimator.ofFloat(view, "rotationY", 180f).start()
Java
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator.ofFloat(view, "rotationY", 180).start();
Vì các lớp phủ phần cứng tiêu thụ bộ nhớ video, bạn chỉ nên bật các lớp phủ đó trong thời lượng của ảnh động rồi tắt sau khi ảnh động hoàn tất. Bạn có thể thực hiện việc này bằng cách sử dụng trình nghe ảnh động:
Kotlin
view.setLayerType(View.LAYER_TYPE_HARDWARE, null) ObjectAnimator.ofFloat(view, "rotationY", 180f).apply { addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { view.setLayerType(View.LAYER_TYPE_NONE, null) } }) start() }
Java
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } }); animator.start();
Để biết thêm thông tin về thuộc tính ảnh động, hãy xem phần Thuộc tính ảnh động.
Mẹo và thủ thuật
Việc chuyển sang đồ hoạ 2D được tăng tốc phần cứng có thể làm tăng hiệu suất ngay lập tức, nhưng bạn vẫn nên thiết kế ứng dụng để dùng GPU sao cho hiệu quả bằng cách làm theo các đề xuất sau:
- Giảm số thành phần hiển thị trong ứng dụng của bạn
- Hệ thống phải vẽ càng nhiều thành phần hiển thị thì tốc độ xử lý càng chậm. Điều này cũng đúng đối với quy trình kết xuất hình ảnh dựa trên phần mềm. Giảm số thành phần hiển thị là một trong những cách đơn giản nhất để tối ưu hoá giao diện người dùng.
- Tránh vẽ nhiều lần
- Không vẽ quá nhiều lớp phủ chồng lên nhau. Xoá mọi thành phần hiển thị bị che khuất hoàn toàn bởi các thành phần hiển thị mờ khác ở phía trên. Nếu bạn cần vẽ nhiều lớp phủ chồng lên nhau, hãy cân nhắc hợp nhất các lớp phủ này thành một lớp phủ duy nhất. Một nguyên tắc hay là phần cứng hiện tại không nên vẽ quá 2,5 lần số pixel trên màn hình cho mỗi khung hình (kể cả số pixel trong suốt mà bitmap tính đến).
- Không tạo đối tượng kết xuất trong các phương thức vẽ
- Một lỗi thường gặp là tạo một
Paint
mới hoặc mộtPath
mới mỗi khi gọi một phương thức kết xuất hình ảnh. Điều này buộc trình thu gom rác phải chạy thường xuyên hơn, đồng thời bỏ qua các bộ nhớ đệm và tính năng tối ưu hoá trong quy trình phần cứng. - Không chỉnh sửa hình dạng quá thường xuyên
- Ví dụ: các hình dạng phức tạp, các đường dẫn và vòng tròn được kết xuất bằng mặt nạ hoạ tiết. Mỗi lần tạo hoặc sửa đổi một đường dẫn, quy trình phần cứng sẽ tạo một mặt nạ mới. Điều này có thể gây hao tốn tài nguyên.
- Không sửa đổi bitmap quá thường xuyên
- Mỗi khi bạn thay đổi nội dung của bitmap, thông tin này sẽ được tải lên lại dưới dạng một hoạ tiết GPU vào lần tiếp theo bạn vẽ.
- Thận trọng khi sử dụng alpha
- Khi bạn tạo một thành phần hiển thị trong suốt bằng cách sử dụng
setAlpha()
,AlphaAnimation
hoặcObjectAnimator
, thành phần hiển thị đó sẽ được kết xuất trong vùng đệm ngoài màn hình và làm tăng gấp đôi tỷ lệ đáp ứng bắt buộc. Khi áp dụng alpha trên các thành phần hiển thị rất lớn, hãy cân nhắc thiết lập kiểu lớp phủ của thành phần hiển thị thànhLAYER_TYPE_HARDWARE
.