Theo mặc định, R8 thực hiện nhiều hoạt động tối ưu hoá để cải thiện hiệu suất và kích thước, nhưng các hoạt động tối ưu hoá này có thể không hoạt động ngay lập tức cho ứng dụng của bạn. Nếu bạn bật R8 (hoặc bật chế độ đầy đủ) lần đầu tiên trong một ứng dụng lớn, hãy thử áp dụng các hoạt động tối ưu hoá theo từng bước: tạm thời tắt tính năng làm rối mã nguồn và bật R8 cho từng phần mã, thay vì cho tất cả mã trong ứng dụng. Bạn nên áp dụng phương pháp gia tăng này trong quá trình phát triển cục bộ, nhưng bạn cũng có thể sử dụng phương pháp này trong quá trình kiểm thử Đảm bảo chất lượng nội bộ hoặc thậm chí trong phiên bản phát hành công khai dưới dạng bản phát hành dần. Các bước chính xác mà bạn thực hiện phụ thuộc vào tiến trình thời gian mong muốn và mức độ tin tưởng vào phạm vi kiểm thử bản phát hành trước.
Giới hạn các hoạt động tối ưu hoá
R8 thực hiện nhiều loại hoạt động tối ưu hoá, bao gồm xoá mã, viết lại mã và xoá tài nguyên. Sau đây là một số nội dung mô tả cấp cao về các loại hoạt động tối ưu hoá:
- Rút gọn mã (hoặc rung cây): xoá mã không được tham chiếu
- Làm rối mã nguồn (hoặc thu gọn mã nhận dạng): rút ngắn tên của các lớp và phương thức
- Tối ưu hoá: viết lại mã, ví dụ: nội tuyến
Để giảm khả năng xảy ra lỗi, bạn có thể bắt đầu bằng cách chỉ bật một số hoạt động tối ưu hoá này.
Chỉ bật tính năng rung cây
Rút gọn mã, còn được gọi là rung cây, xoá mã có vẻ không được tham chiếu. Bạn nên bắt đầu chỉ với tính năng rung cây, vì đây là tính năng đơn giản nhất.
Để chỉ bật tính năng rung cây, hãy thêm nội dung sau vào tệp proguard-rules.pro để tắt các loại hoạt động tối ưu hoá khác. Việc tắt tính năng làm rối mã nguồn là rất quan trọng vì tính năng này giúp bạn đọc dấu vết ngăn xếp dễ dàng hơn nhiều.
-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization
Cuối cùng, bạn không nên phát hành cấu hình này vì nó hạn chế đáng kể khả năng tối ưu hoá mã của R8, nhưng đây là điểm khởi đầu tuyệt vời khi áp dụng R8 lần đầu tiên trong một cơ sở mã lớn có các vấn đề cần khắc phục.
Sử dụng chế độ tương thích
Theo mặc định, R8 chạy ở chế độ đầy đủ. Chế độ đầy đủ giúp cải thiện đáng kể hiệu suất và tiết kiệm kích thước, nhưng bạn có thể tạm thời tắt chế độ này và sử dụng chế độ tương thích thay thế khi bật tính năng rút gọn lần đầu tiên.
Để sử dụng chế độ tương thích, hãy sử dụng chế độ cài đặt sau trong tệp gradle.properties:
android.enableR8.fullMode = false // Use temporarily to disable full mode
Bật các hoạt động tối ưu hoá còn lại
Khi đã xác nhận rằng tính năng rung cây hoạt động cho ứng dụng của bạn, bạn có thể xoá các chế độ cài đặt trước đó để bật lại tính năng làm rối mã nguồn, tối ưu hoá và chế độ đầy đủ của R8. Xin lưu ý rằng tính năng làm rối mã nguồn có thể khiến quá trình gỡ lỗi trở nên khó khăn hơn. Đó là lý do bạn nên giải quyết các vấn đề về tính năng rung cây trước.
Để biết thêm thông tin về cách gỡ rối mã nguồn cho dấu vết ngăn xếp, hãy xem phần Khôi phục dấu vết ngăn xếp ban đầu.
Giới hạn phạm vi tối ưu hoá
Bản dựng được tối ưu hoá hoàn toàn sẽ tối ưu hoá tất cả mã trên mọi thư viện và gói, vì vậy, bạn thường gặp phải các vấn đề với R8 khi bật R8 lần đầu tiên. Nếu bạn gặp vấn đề về hoạt động tối ưu hoá ở một phần của ứng dụng, đừng tắt hoàn toàn R8, nếu không bạn sẽ mất các lợi ích ở mọi nơi khác. Thay vào đó, hãy tạm thời tắt R8 chỉ ở những phần của ứng dụng đang gây ra vấn đề.
Sử dụng quy tắc giữ lại trên toàn gói
Bạn nên sử dụng quy tắc giữ lại trên toàn gói để tạm thời tắt R8 ở một số phần của ứng dụng. Bạn nên luôn quay lại để khắc phục các vấn đề tối ưu hoá này sau; đây thường là giải pháp tạm thời để giải quyết các khu vực có vấn đề.
Ví dụ: nếu một phần của ứng dụng sử dụng nhiều Gson và đang gây ra các vấn đề về
hoạt động tối ưu hoá, thì giải pháp lý tưởng là thêm các
quy tắc giữ lại có mục tiêu hơn hoặc chuyển sang giải pháp codegen. Tuy nhiên, để bỏ chặn hoạt động tối ưu hoá phần còn lại của ứng dụng, bạn có thể đặt mã xác định các loại Gson trong một gói con riêng và thêm một quy tắc như sau vào tệp proguard-rules.pro:
-keep class com.myapp.json.** { *; }
Nếu một số thư viện mà bạn đang sử dụng có phản ánh vào các thành phần nội bộ, bạn cũng có thể thêm quy tắc giữ lại cho toàn bộ thư viện. Bạn cần kiểm tra mã hoặc JAR/AAR của thư viện để tìm gói thích hợp cần giữ lại. Xin nhắc lại rằng bạn không nên duy trì quy tắc này trong dài hạn, nhưng có thể bỏ chặn hoạt động tối ưu hoá phần còn lại của ứng dụng:
-keep class com.somelibrary.** { *; }
Xoá quy tắc giữ lại trên toàn gói
Sau khi ứng dụng của bạn hoạt động chính xác với các quy tắc giữ lại trên toàn gói, bạn nên go back và thêm các quy tắc giữ lại có mục tiêu hoặc xoá việc sử dụng phản ánh hoặc thư viện mà ban đầu cần quy tắc giữ lại.
Ví dụ: việc giữ lại tất cả các quy tắc mở rộng một lớp nhất định là cực kỳ phổ biến trong AndroidX để chỉ giữ lại các lớp có liên quan. Nói chung, phản ánh chỉ nhắm đến các lớp hoặc phương thức mở rộng một số lớp trừu tượng nhất định, triển khai một số giao diện nhất định hoặc vào các lớp có chú thích thời gian chạy cụ thể. Mỗi cách này đều là cách được hỗ trợ để xác định quy tắc giữ lại, nhờ đó bạn không cần quy tắc giữ lại trên toàn gói trong ứng dụng cuối cùng được tối ưu hoá hoàn toàn.
Nếu có phản ánh trong toàn bộ mã nguồn của riêng bạn, bạn có thể thay thế các quy tắc giữ lại trên toàn gói bằng Jetpack Keep. Các quy tắc được tạo là có điều kiện: R8 chỉ giữ lại mục tiêu của lệnh gọi phản ánh nếu R8 cũng giữ lại mã thực hiện lệnh gọi đó. Để di chuyển một gói, hãy sử dụng các lượt kiểm tra lint của Jetpack Keep để tìm và chú thích các lệnh gọi phản ánh của gói đó, sau đó xoá quy tắc trên toàn gói.