Khi bạn bật tính năng tối ưu hoá ứng dụng bằng các chế độ cài đặt mặc định, R8 sẽ thực hiện các quy trình tối ưu hoá trên diện rộng để tối đa hoá lợi ích về hiệu suất. R8 sửa đổi đáng kể mã, bao gồm cả việc đổi tên, di chuyển và xoá các lớp, trường và phương thức. Nếu nhận thấy những nội dung sửa đổi này gây ra lỗi, bạn cần chỉ định những phần mã mà R8 không nên sửa đổi bằng cách khai báo những phần đó trong quy tắc lưu giữ.
Các trường hợp phổ biến cần có quy tắc giữ lại
R8 xác định và giữ lại tất cả các lệnh gọi trực tiếp trong mã của bạn. Tuy nhiên, R8 không thể nhận thấy các cách sử dụng mã gián tiếp. Điều này có thể khiến R8 xoá mã mà ứng dụng của bạn cần, dẫn đến lỗi. Sử dụng quy tắc giữ lại để yêu cầu R8 giữ lại mã được dùng gián tiếp như vậy. Sau đây là một số trường hợp phổ biến mà bạn có thể cần đến quy tắc giữ lại:
- Mã được truy cập bằng cơ chế phản chiếu: R8 không thể xác định thời điểm các lớp, trường hoặc phương thức được truy cập bằng cơ chế phản chiếu. Ví dụ: R8 không thể xác định một phương thức được tra cứu theo tên bằng cách sử dụng
Class.getDeclaredMethod()hoặc một chú thích được truy xuất bằngClass.getAnnotation(). Trong những trường hợp này, R8 có thể đổi tên các phương thức và chú thích này hoặc xoá hoàn toàn chúng, dẫn đếnClassNotFoundExceptionhoặcNoSuchMethodExceptiontrong thời gian chạy. - Mã được gọi từ Giao diện gốc Java (JNI): Khi mã gốc (C hoặc C++) gọi một phương thức Java hoặc Kotlin, hoặc mã Java hoặc Kotlin gọi mã C++ bằng JNI, lệnh gọi sẽ dựa trên một hoạt động tra cứu chuỗi động về tên của phương thức. R8 không thể thấy lệnh gọi phương thức dựa trên chuỗi động, do đó, các hoạt động tối ưu hoá của R8 có thể làm hỏng mã của bạn.
Đây không phải là danh sách đầy đủ các trường hợp cần có quy tắc giữ lại, nhưng những trường hợp này bao gồm hầu hết các trường hợp mà bạn có thể cần đến quy tắc giữ lại.
Cách thêm quy tắc giữ lại vào ứng dụng
Cấu hình quy tắc giữ lại của bạn phụ thuộc vào phiên bản AGP mà bạn sử dụng.
Các ứng dụng có kích thước lớn thường có mã trong nhiều mô-đun thư viện. Trong những trường hợp như vậy, bạn thường nên đặt các quy tắc giữ lại cùng với mã mà chúng áp dụng trong mô-đun thư viện cụ thể. Sự khác biệt quan trọng trong việc duy trì các quy tắc giữ lại cho thư viện nằm ở cách bạn khai báo các quy tắc này trong tệp build.gradle.kts (hoặc build.gradle) của mô-đun thư viện. Hãy xem phần Tối ưu hoá cho tác giả thư viện để tìm hiểu thêm.
Đối với AGP phiên bản 9.3 trở lên
Thêm các quy tắc vào một tệp có hậu tố .keep trong thư mục src/<variant>/keepRules. Ví dụ: src/main/keepRules/custom-rules.keep Xin lưu ý rằng việc sử dụng DSL được cập nhật cho AGP 9.3 trở lên sẽ cho phép tối ưu hoá cả mã và tài nguyên, đồng thời không yêu cầu bạn xác định rõ tệp quy tắc giữ mặc định của Android (proguard-android-optimize.txt), vì tệp này được đưa vào theo mặc định, trừ phi bạn bỏ qua một cách rõ ràng.
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
Groovy
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
Bỏ qua các quy tắc giữ mặc định của nền tảng Android (Nâng cao)
AGP cung cấp một bộ quy tắc mặc định cho nền tảng Android. Để bỏ qua các quy tắc này trong cấu hình của dự án và tự quản lý tất cả các quy tắc lưu giữ, hãy đặt optimization.keepRules.includeDefault thành false.
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
Groovy
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
DSL cũ cho các phiên bản AGP thấp hơn 9.3
Thêm các quy tắc của bạn vào tệp proguard-rules.pro nằm trong thư mục gốc của mô-đun ứng dụng. Tệp này có thể đã có sẵn, nhưng nếu chưa có, hãy tạo tệp này. Để áp dụng các quy tắc trong tệp, bạn phải khai báo tệp đó trong tệp build.gradle.kts (hoặc build.gradle) ở cấp mô-đun.
Theo mặc định, tệp bản dựng của bạn cũng bao gồm tệp proguard-android-optimize.txt. Tệp này chứa các quy tắc bắt buộc đối với hầu hết các dự án Android, vì vậy bạn nên giữ nguyên tệp này trong tệp bản dựng. Tệp này dựa trên và chia sẻ nội dung với tệp proguard-common.txt.
DSL cũ (Kotlin)
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
// Default file with default optimization rules.
getDefaultProguardFile("proguard-android-optimize.txt"),
...
)
}
}
}
DSL cũ (Groovy)
android {
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
// Default file with default optimization rules.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
...
}
}
}
Thêm quy tắc giữ lại
Khi thêm quy tắc giữ lại, bạn có thể thêm các lựa chọn chung cũng như xác định quy tắc giữ lại của riêng mình.
Các lựa chọn chung: Các lựa chọn chung là những chỉ thị chung ảnh hưởng đến cách R8 hoạt động trên toàn bộ mã nguồn của bạn. Để tìm hiểu thêm, hãy xem phần Các lựa chọn chung.
Quy tắc giữ lại: Bạn cần thiết kế quy tắc giữ lại một cách cẩn thận để đảm bảo đạt được sự cân bằng phù hợp giữa việc tối đa hoá hoạt động tối ưu hoá mã mà không vô tình làm hỏng ứng dụng của bạn. Để tìm hiểu cách viết quy tắc giữ lại, hãy xem phần Thêm quy tắc giữ lại.
Quy tắc giữ lại cho tác giả thư viện
Sau khi tìm hiểu về các lựa chọn chung và cú pháp cho quy tắc giữ lại, hãy xem phần Tối ưu hoá cho tác giả thư viện để biết thêm thông tin chi tiết.