Khi làm việc với các quy tắc giữ lại, điều quan trọng là bạn phải đạt được mức độ cụ thể phù hợp để đảm bảo bạn thấy được lợi ích trong khi vẫn duy trì hành vi của ứng dụng. Hãy xem các phần sau để tìm hiểu về các mẫu tốt cũng như những điều cần tránh trong quy tắc giữ lại.
Các mẫu hay trong quy tắc giữ lại
Các quy tắc giữ lại được xác định rõ ràng và cụ thể nhất có thể:
Đối với quy cách lớp, hãy luôn chỉ định một lớp cụ thể, lớp cơ sở hoặc lớp được chú thích nếu có thể, như trong các ví dụ sau:
-keepclassmembers class com.example.MyClass { void someSpecificMethod(); }
-keepclassmembers ** extends com.example.MyBaseClass { void someSpecificMethod(); }
-keepclassmembers @com.example.MyAnnotation class ** { void someSpecificMethod(); }
Bất cứ khi nào có thể, hãy sử dụng chú thích trên mã nguồn (chẳng hạn như chú thích
@Keep
) rồi nhắm đến những chú thích đó ngay trong các quy tắc lưu giữ. Điều này tạo ra một mối liên kết rõ ràng, tường minh giữa mã của bạn và các quy tắc duy trì mã đó, giúp cấu hình của bạn mạnh mẽ hơn, dễ hiểu hơn và ít bị lỗi hơn khi mã thay đổi.Ví dụ: các thư viện như
androidx.annotation
sử dụng mẫu này:// In your source code @Keep class MyDataClass { /* ... */ } // In your R8 rules -keep @androidx.annotation.DisplayComponent class * {*;}
Bạn nên đặt tên cho chú thích sao cho chúng cung cấp ngữ cảnh có ý nghĩa về lý do các phần mã được giữ lại. Ví dụ: sử dụng
@DisplayComponent
cho một ứng dụng mà các thành phần hiển thị yêu cầu phải giữ lại một số phần.Bất cứ khi nào có thể, bạn nên khai báo quy cách thành viên và chỉ tham chiếu đến những phần của lớp phải được giữ lại để ứng dụng hoạt động. Bạn không nên áp dụng một quy tắc cho toàn bộ lớp bằng cách xác định phạm vi thành viên không bắt buộc là
{ *; }
, trừ phi thực sự cần thiết.-keepclassmembers com.example.MyClass { void someSpecificMethod(); void @com.example.MyAnnotation *; }
Nếu bạn sử dụng lựa chọn chung
repackageclasses
, hãy tránh chỉ định tên gói không bắt buộc. Điều này giúp giảm kích thước tệp DEX vì tiền tố gói bị bỏ qua trong tên lớp được đóng gói lại.
Nếu không tuân thủ các nguyên tắc này, bạn có thể tạm thời tách biệt mã cần giữ lại trong một gói chuyên dụng và áp dụng quy tắc giữ lại cho gói đó. Tuy nhiên, đây không phải là giải pháp lâu dài. Để tìm hiểu thêm, hãy xem bài viết Từng bước áp dụng các hoạt động tối ưu hoá. Để sử dụng quy tắc giữ lại cho một gói, hãy xác định quy tắc giữ lại như trong ví dụ sau:
-keepclassmembers class com.example.pkg.** { *; }
Những điều nên tránh
Cú pháp quy tắc giữ lại có nhiều lựa chọn, nhưng để có được những lợi ích về hiệu suất bền vững có thể đo lường được, bạn không nên sử dụng những lựa chọn sau:
- Tránh sử dụng toán tử đảo ngược
!
trong các quy tắc giữ lại vì bạn có thể vô tình áp dụng một quy tắc cho hầu hết mọi lớp trong ứng dụng của mình. - Đừng sử dụng các quy tắc giữ lại trên toàn gói, chẳng hạn như
-keep class com.example.pkg.** { *; }
trong thời gian dài. Bạn có thể tạm thời sử dụng các quy tắc này để giải quyết các vấn đề khi định cấu hình R8. Để biết thêm thông tin, hãy xem phần Giới hạn phạm vi tối ưu hoá. Nhìn chung, hãy cẩn thận với ký tự đại diện – đảm bảo rằng bạn chỉ giữ lại mã mà bạn cần.
Nếu không tuân theo các quy tắc này, có thể bạn đang sử dụng nhiều hoạt động phản chiếu không giới hạn và nên tránh hoạt động phản chiếu hoặc tránh thư viện bằng cách sử dụng hoạt động phản chiếu (xem nghiên cứu điển hình về Gson).