Trong khi làm việc với các quy tắc giữ lại, bạn cần phải đạt được mức độ cụ thể phù hợp để đảm bảo 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 hữu ích cũng như những điều cần tránh trong các quy tắc giữ lại.
Các mẫu hữu ích trong quy tắc giữ lại
Các quy tắc giữ lại được xác định rõ ràng sẽ cụ thể nhất có thể và tuân thủ các mẫu sau:
Đối với thông số kỹ thuật của 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, sau đó nhắm mục tiêu trực tiếp đến những chú thích đó trong các quy tắc giữ lại. Đ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 giữ lại 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ụ: đoạn mã sau đây minh hoạ cách bạn có thể giữ lại lớp MyClass, cũng như các lớp khác được chú thích bằng
@com.example.DisplayComponent:// In the source code @com.example.DisplayComponent class MyClass { /* ... */ } // In the keep rules -keep @com.example.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 giữ lại các phần mã. Ví dụ: hãy sử dụng
@DisplayComponentcho một ứng dụng mà các thành phần hiển thị yêu cầu giữ lại một số phần.Bất cứ khi nào có thể, bạn nên khai báo thông số kỹ thuật của thành phần và chỉ tham chiếu đến các 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 quy tắc cho toàn bộ lớp bằng cách xác định phạm vi thành phầ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
repackageclassestuỳ chọn chung, hãy tránh chỉ định tên gói không bắt buộc. Điều này giúp tạo ra các tệp DEX nhỏ hơn vì tiền tố gói bị bỏ qua trong tên lớp được đóng gói lại.Duy trì các quy tắc giữ lại cho tất cả các mục được truy cập bằng cách phản ánh. Ngay cả khi R8 giữ lại các mục như vậy mà không có quy tắc giữ lại rõ ràng, việc duy trì các quy tắc thực tế là rất quan trọng vì các thay đổi mã trong tương lai có thể khiến R8 không còn giữ lại các mục này nữa.
Đối với việc phản ánh trong mã của riêng bạn, bạn có thể sử dụng Jetpack Keep để tạo các quy tắc giữ lại dễ duy trì hơn. Mỗi chú thích đều nằm trên mã thực hiện việc phản ánh, vì vậy, khi thay đổi mã đó, bạn sẽ cập nhật hoặc xoá chú thích của mã đó ở cùng một vị trí. Bằng cách đó, các quy tắc sẽ không giữ lại mã mà ứng dụng của bạn không còn phản ánh nữa. Lint cũng gắn cờ các lệnh gọi phản ánh không được chú thích.
Nếu có thể, hãy sử dụng
-assumenosideeffectshoặc-convertchecknotnullđể tối ưu hoá các lượt kiểm tra giá trị rỗng vì điều này có thể làm giảm đáng kể kích thước DEX của ứng dụng. Để biết thêm thông tin, hãy xem phần Các loại quy tắc bổ sung.
Nếu không thể 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 riê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 phần Từng bước áp dụng các phương pháp 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 tuỳ chọn, nhưng để có được 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 tuỳ chọn sau:
- Không sử dụng các quy tắc giữ lại trên toàn gói như
-keep class com.example.pkg.** { *; }trong dài hạn. 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ã cần thiết. - Nếu có thể, hãy tránh các thư viện đề xuất bạn sao chép và dán các quy tắc giữ lại khi sử dụng chúng, đặc biệt là các quy tắc giữ lại trên toàn gói. Các thư viện được thiết kế để hoạt động tốt trên Android nên tránh việc phản ánh nếu có thể và nhúng các quy tắc giữ lại của bên sử dụng thư viện khi cần thiết.
- 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 quy tắc cho hầu hết mọi lớp trong ứng dụng.
Nếu không thể tuân theo các quy tắc này, bạn có thể đang sử dụng nhiều phương thức phản ánh mở và nên tránh việc phản ánh hoặc tránh thư viện sử dụng phương thức phản ánh (xem nghiên cứu điển hình về Gson).