Mobile Development 14 min read

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.

Baidu App Technology
Baidu App Technology
Baidu App Technology
How Baidu Shrunk Android App Size by Optimizing Dex Annotations

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 visibility
Dex annotation visibility

Dex Annotation Format

In Dex, annotations are expressed in smali syntax:

.annotation [annotation attributes] <annotation class>
    [field = value]
.end annotation

For a method‑level annotation @SuppressLint("BanParcelableUsage"), the smali representation is:

.annotation build Landroid/annotation/SuppressLint;
    value = {"BanParcelableUsage"}
.end annotation

Optimization 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).

Removable annotations
Removable annotations

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AndroidbytecodeGradleDEXlintAnnotation OptimizationTitan-Dex
Baidu App Technology
Written by

Baidu App Technology

Official Baidu App Tech Account

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.