Sử dụng quy tắc để khắc phục sự cố tối ưu hoá

Ngoài quy tắc giữ lại chung, các loại quy tắc giữ lại kháccác lựa chọn chung, bạn có thể sử dụng một số quy tắc để khắc phục vấn đề về việc tối ưu hoá.

-checkdiscard

Quy tắc -checkdiscard cho phép bạn kiểm tra xem R8 có loại bỏ thành công một lớp hoặc thành viên của lớp mà bạn muốn xoá hay không. Nếu lớp hoặc thành phần được chỉ định không bị loại bỏ, thì bản dựng sẽ không thành công.

Cú pháp cho -checkdiscard như sau:


-checkdiscard <class_specification>

Trong ví dụ sau, bản dựng sẽ không thành công nếu bạn giữ lại trường userId hoặc phương thức setLabel() từ lớp com.example.models.User:

-checkdiscard class com.example.models.User{
  private java.lang.String userId;
  public void setLabel(java.lang.String);
}

Mã của lớp vẫn có thể xuất hiện trong ứng dụng nếu các phương thức của lớp được nội tuyến hoá vào các lớp khác. Để đảm bảo rằng mã đã được xoá hoàn toàn chứ không chỉ được nội tuyến, hãy thêm một quy tắc tương ứng ngăn R8 thực hiện các hoạt động tối ưu hoá trên lớp mục tiêu, bằng cách kết hợp -checkdiscard với quy tắc -keep,allowshrinking. Điều này cấm các hoạt động tối ưu hoá như hợp nhất và chèn cùng dòng lớp. Nếu quy tắc -checkdiscard được thông qua, thì không có nội dung nào trong các lớp được so khớp nằm trong ứng dụng được tối ưu hoá.

Ví dụ sau đây minh hoạ cách sử dụng này:

# Either keep or remove the class, don't rename or otherwise optimize it
-keep,allowshrinking class com.example.foo { *; }

# Verify that the class and all of its fields and methods are removed.
-checkdiscard class com.example.foo

-whyareyoukeeping

Sử dụng quy tắc -whyareyoukeeping để xác định lý do R8 giữ lại một lớp, trường hoặc phương thức cụ thể trong bản dựng ứng dụng của bạn. Một mục có thể được giữ lại vì nhiều lý do; tuy nhiên, quy tắc này chỉ cung cấp lý do giải thích đường dẫn ngắn nhất đến mục đó từ một mục được giữ lại. Nếu xoá đường dẫn này khỏi mã, bạn vẫn có thể thấy mục được giữ lại nhưng vì một lý do khác.

Các lý do có thể là:

  • Quy tắc lưu giữ: Quy tắc lưu giữ có thể đến từ ứng dụng, một thư viện đã dùng hoặc các quy tắc do AAPT (Công cụ đóng gói tài sản Android) tạo.

  • Các tham chiếu bắc cầu từ mã hoặc tài nguyên được giữ lại: Nếu mã hoặc XML (chẳng hạn như bố cục) được R8 giữ lại, thì mọi thứ mà mã hoặc XML tham chiếu tĩnh đều sẽ được giữ lại.

Cú pháp là:


-whyareyoukeeping <class_specification>

Ví dụ:

-whyareyoukeeping class com.example.foo.MainActivity {
  private void setLabel(...);
}

Kết quả được in ra bảng điều khiển.

Nếu bạn không có quy tắc nào giữ lại setLabel(), thì đầu ra sẽ là:

com.example.foo.MainActivity
|- is referenced in keep rule:
|  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
Nothing is keeping void com.example.foo.MainActivity.setLabel()

Nếu bạn có một quy tắc giữ lại nhắm đến setLabel(), thì kết quả sẽ tương tự như sau:

com.example.foo.MainActivity
|- is referenced in keep rule:
| /app/proguard-rules.pro:23:1
void com.example.foo.MainActivity.setLabel()
|- is referenced in keep rule:
|  /app/proguard-rules.pro:23:1