Baidu App Android APK Resource Optimization Practices
The article details Baidu App’s third‑stage Android APK size reduction, explaining the res/ and assets structure, reviewing AGP’s OptimizeResources, ShrinkResources and new flags, and describing a custom AAPT2‑based tool that shortens paths and filenames, removes extensions, collapses names, uses sparse encoding, integrates third‑party guards and image‑compression techniques to significantly shrink the package.
This article is the third part of Baidu App Android package size optimization series, focusing on resource optimization. It introduces the structure of APK resources (the res/ directory, resources.arsc , and assets/ ) and explains why there is room for size reduction.
The author reviews existing resource‑optimization tools, including the Android Gradle Plugin (AGP) tasks that rely on AAPT2: OptimizeResources , ShrinkResources , resConfigs , and splits . The android.enableResourceOptimizations flag can disable these tasks, while AGP 4.2+ adds new parameters such as --shorten-resource-paths , --collapse-resource-names , and --enable-sparse-encoding to control path shortening, name collapsing, and sparse encoding.
Key code from the AGP implementation shows the flags used by OptimizeResourcesTask :
// com/android/build/gradle/internal/tasks/OptimizeResourcesTask.class
// OptimizeResourcesTask关联了AAPT2提供的优化项
enum class AAPT2OptimizeFlags(val flag: String) {
COLLAPSE_RESOURCE_NAMES("--collapse-resource-names"),
SHORTEN_RESOURCE_PATHS("--shorten-resource-paths"),
ENABLE_SPARSE_ENCODING("--enable-sparse-encoding")
}
internal fun doFullTaskAction(params: OptimizeResourcesTask.OptimizeResourcesParams) {
val optimizeFlags = mutableSetOf(
AAPT2OptimizeFlags.SHORTEN_RESOURCE_PATHS.flag
)
if (params.enableResourceObfuscation.get()) {
optimizeFlags += AAPT2OptimizeFlags.COLLAPSE_RESOURCE_NAMES.flag
}
}Based on the analysis, Baidu App builds a custom resource‑optimization tool on top of AAPT2. Its design goals are multi‑format support (APK and AAB), forward‑compatible AGP integration, and stability.
The tool applies three main optimizations:
Resource‑path shortening: replaces long directory structures (e.g., res/type‑qualifier ) with a short prefix like r/ .
File‑name shortening: generates a three‑character name using a consistent hash function. Example implementation:
std::string ShortenFileName(const android::StringPiece& file_path, int output_length) {
size_t hash_num = std::hash
{}(file_path);
std::string result = "";
for (int i = 0; i < output_length; i++) {
uint8_t sextet = hash_num & 0x3f;
hash_num >>= 6;
result += base64_chars[sextet];
}
return result;
}Extension removal: drops file extensions for non‑XML resources while keeping them for res/color and res/drawable XML files, as shown in the source check:
if (util::StartsWith(res_subdir, "res/color") || util::StartsWith(res_subdir, "res/drawable")) {
if (util::StartsWith(extension, ".xml")) {
keep_extensions = true;
}
}Additional optimizations include resource‑name collapsing (making all names identical except for a whitelist), enabling sparse entry encoding, and integrating third‑party tools such as AndResGuard and AabResGuard for further shrinking and obfuscation.
The article also covers auxiliary techniques: lossless image compression with ImageOptim, detection of duplicate and similar resources (using MD5 or OpenCV feature matching), and the shift toward declarative UI (Jetpack Compose) which can reduce APK size by up to 41%.
Finally, the author summarizes the overall impact of these optimizations on Baidu App’s APK size and invites feedback.
Baidu App Technology
Official Baidu App Tech Account
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.