[Smaller APK part 3]Removing unused resources
Trong phần tiếp theo của loạt bài tối ưu kích thước file apk, tôi trình bày về các phương pháp để loại bỏ các tài nguyên không dùng đến trong ứng dụng. Tài nguyên (Resources) ở đây gồm nhiều loại: ảnh chuỗi (string), layout file, dimension... Có 2 cách để loại bỏ tài nguyên không dùng đến ...
Trong phần tiếp theo của loạt bài tối ưu kích thước file apk, tôi trình bày về các phương pháp để loại bỏ các tài nguyên không dùng đến trong ứng dụng.
Tài nguyên (Resources) ở đây gồm nhiều loại:
- ảnh
- chuỗi (string), layout file, dimension...
Có 2 cách để loại bỏ tài nguyên không dùng đến trong ứng dụng (đây là những resource không dùng đến nhưng có phụ thuộc vào thành phần khác mà không loại bỏ được bằng tay). Cách 1: sử dụng cờ minify/shinking tương tự như ở part2
android { ... buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
Tương tự với loại bỏ mã code, loại bỏ resource cũng xảy ra một vấn đề là loại bỏ nhầm tài nguyên được sử dụng. Để tránh tình trạng này bạn có thể dùng keep để tạo ngoại lệ cho các tài nguyên không muốn tự động shrink
Trong file res/raw/keep.xml
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*" />
hoặc sử dụng discard, ở cùng file keep.xml
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkMode="safe" tools:discard="@layout/unused2" />
Bạn có thể đọc thêm về debugging shrink bằng log file và chuyển chế độ safe và strict ở trang sau
https://tools.android.com/tech-docs/new-build-system/resource-shrinking
Tất nhiên tốt nhất bạn nên kiểm soát thật tốt tài nguyên và loại bỏ bằng tay các tài nguyên mà ban chắc chắn không sử dụng đến thay vì sử dụng tools tự động.
Loại bỏ những config dư thừa với ResConfigs
Có rất nhiều thư viện hỗ trợ multi language. Support Library và Google Play Services là một ví dụ. Nếu bạn không có nhu cầu sử dụng multi language, bạn có thể loại bỏ nó bằng cách sau:
android { defaultConfig { ... resConfigs "en", "fr" } }
Sparse configurations in resources.arsc
Vấn đề mà tôi đề cập đến ở phần này sẽ dành cho những ứng dụng có dung lượng lớn với hàng trăm hay hàng nghìn chuỗi, styles... ở trong file resources.arsc
Nếu bạn nhận thấy tập tin này chiếm một số lượng lớn bất thường trong APK file, điều này có thể chỉ báo rằng bạn có quá nhiều cấu hình dạng spare (tạm dịch là rải rác). Xem ví dụ sau để hiểu rõ hơn:
Nếu bạn khai báo 5 chuỗi trong file strings, các string sẽ được cấp phát như thế này
String pool: "My App", "Hello", "Exit", "Settings", "Feature" Default config: string/myapp 0x00000001 string/hello 0x00000002 string/exit 0x00000003 string/settings 0x00000004 string/feature 0x00000005
Bây giờ bạn muốn override 1 strings cho v21 chẳng hạn, lúc đó, bạn khai báo thêm một strings.xml trong v21. Lúc đó, bạn nghĩ đơn giản mình vừa khai báo thêm một xâu nữa thôi, nhưng sự thật thì các đối tượng được cấp phát như thế này:
String pool: "My App", "Hello", "Exit", "Settings", "Feature", "New feature" Default config: -v21 config: string/myapp 0x00000001 NO_ENTRY string/hello 0x00000002 NO_ENTRY string/exit 0x00000003 NO_ENTRY string/settings 0x00000004 NO_ENTRY string/feature 0x00000005 0x00000006 ========== ========== Config size: 20 bytes 20 bytes!
Nhìn xem, ở v21 sinh ra các value null nhưng value này vẫn dành 4 bytes cấp phát. Bạn có thể tưởng tượng ra ảnh hưởng của việc này chưa?
Ví dụ ứng dụng có 50 ngôn ngữ, với khoảng 3500 strings, lúc đó dung tích thêm là:
4 bytes * 3500 null entries * 50 languages = 700 kilobytes
thế là 700 kB có thể được tiết kiệm bởi cách xoá một strings. Với 3 strings thì bạn sẽ tiết kiệm được 2.5M!
Như vậy trong trường hợp ứng dụng có nhiều resource, việc tạo thêm 1 resource bằng cách hợp lý bằng cách xem xét có thật sự cần thiết để tạo folder resource mới hay không.
May mắn là Google có một công cụ có thể giúp bạn tìm ra những tài nguyên dạng sparse, nó gọi là ArscBlamer và có thể tìm thấy ở đây
https://github.com/google/android-arscblamer
$ bazel run //java/com/google/devrel/gmscore/tools/apk/arsc:ArscDumper --apk=/FULL_PATH_TO_APK/bar.apk - keys > output.csv
More fun and interesting!
Tool này khá thú vị đấy nhỉ, hi vọng bài viết hữu ích cho các bạn. Happy coding!