How Baidu Shrunk Android App Size by Optimizing Dex Annotations
This article details Baidu's systematic approach to reducing Android APK size by analyzing Dex annotation types, defining removal targets, implementing a Titan‑Dex based optimizer, and automating detection and whitelist management with custom Lint rules, ultimately saving about 1.2 MB of Dex bytecode.
Introduction
Baidu App's Android package size optimization series includes overall strategy, Dex line‑number optimization, and resource optimization. This third part focuses on Dex annotation optimization, which differs from line‑number optimization by targeting unnecessary annotations stored in the Dex file.
Dex Annotation Types
1. Annotation lifecycle classification
RetentionPolicy.SOURCE – discarded after compilation.
RetentionPolicy.CLASS – kept in the .class file but removed by the JVM.
RetentionPolicy.RUNTIME – retained in the class file and available at runtime.
2. Dex annotation visibility classification
Annotations are divided into three visibility categories:
Compile‑time annotations (BUILD) correspond to SOURCE and CLASS retention and are useless at runtime.
Runtime annotations (RUNTIME) correspond to RUNTIME retention.
System annotations (SYSTEM) are used only by the system and have no direct impact on business code.
Dex Annotation Format
In Dex, annotations are expressed in smali syntax:
.annotation [annotation attributes] <annotation class>
[field = value]
.end annotationFor a method‑level annotation @SuppressLint("BanParcelableUsage"), the smali representation is:
.annotation build Landroid/annotation/SuppressLint;
value = {"BanParcelableUsage"}
.end annotationOptimization Goals
Analysis of all Dex annotations identified removable types, mainly:
All BUILD annotations.
System generic annotations (e.g., Ldalvik/annotation/Signature).
Four class‑relationship system annotations ( MemberClasses, InnerClass, EnclosingClass, EnclosingMethod).
Optimization Scheme
The team used Baidu's open‑source bytecode manipulation framework Titan‑Dex to modify Dex annotations directly. A custom Gradle task runs before the packaging task, traverses all classes, methods, and fields, and removes annotations that match the following criteria:
override fun visitClass(dcn: DexClassNode) { /* traverse classes */ }
override fun visitAnnotation(annotationInfo: DexAnnotationVisitorInfo): DexAnnotationVisitor? {
return if (removeAnnotation(annotationInfo, dcn.type.toTypeDescriptor())) null else super.visitAnnotation(annotationInfo)
}
/* similar overrides for methods, parameters, and fields */ private fun removeAnnotation(annotationInfo: DexAnnotationVisitorInfo, classType: String): Boolean {
if (annotationInfo.visibility.name == ANNOTATION_TYPE_BUILD && optBuild) return true
if (!optSystem) return false
when (annotationInfo.type.toTypeDescriptor()) {
ANNOTATION_SIGNATURE, ANNOTATION_INNERCLASS, ANNOTATION_ENCLOSINGMETHOD,
ANNOTATION_ENCLOSINGCLASS, ANNOTATION_MEMBERCLASS -> {
if (classType !in whiteListSet) {
LogUtil.log("系统注解", "需要删除")
return true
}
}
}
return false
}A whitelist mechanism preserves annotations required by reflection APIs.
Automated Detection and Whitelisting
Manual scanning proved cumbersome, so the team built an Android Lint‑based solution with three custom detectors:
ClassShipUseDetector – scans class‑relationship API usage.
SignatureUseDetector – scans generic‑signature API usage.
EncapsulationDetector – scans Gson.fromJson wrappers; when wrapped, developers must add a whitelist entry.
The detection workflow integrates into the warning‑intercept phase during testing, catching issues early.
Exemption Methods
Developers can suppress warnings with @SuppressLint("${detector_name}") or annotate target classes with @KeepAllDavilkAnnotation to keep annotations.
Automated Whitelist Rules
Five whitelist rule types were abstracted and implemented in a Gradle plugin:
Subclass whitelist: ${ParentClass}#superclass Annotation whitelist: ${AnnotationName}#annotation Package whitelist: ${package}.**#package Class whitelist: ${ClassName}#classname Anonymous‑class whitelist: ${EnclosingClass}#anonymous Example entries generated for Baidu App:
com.baidu.searchbox.net.update.v2.AbstractCommandListener#superclass
com.google.gson.reflect.TypeToken#superclass
com.google.gson.annotations.SerializedName#annotation
com.google.gson.**#package
com.alipay.**#package
com.baidu.FinalDb#classname
...During the Gradle Transform phase, all class files are examined; those matching whitelist rules are automatically added to the whitelist, drastically reducing manual effort.
Conclusion
The Dex annotation optimization, combined with automated detection and whitelist generation, reduced Baidu App's Dex size by approximately 1.2 MB, demonstrating the effectiveness of systematic bytecode‑level analysis and tooling.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
