A look into the Android build tools. How are Android apps built? What's new in the Android build tools?
What’s in theAndroid Toolbox?Bryan Herbst(@bryancherbst)
View Slide
What tools?
$ sdkmanager --list
$ sdkmanager --listTools
$ sdkmanager --listToolsPlatform-Tools
$ sdkmanager --listToolsPlatform-ToolsBuild-Tools
SDK tools
$ ls $ANDROID_HOME/tools
$ ls $ANDROID_HOME/toolsandroidemulatormonitor
$ ls $ANDROID_HOME/platform-tools
$ ls $ANDROID_HOME/platform-toolsadbfastbootsystrace
$ ls $ANDROID_HOME/build-tools/27.0.3
$ ls $ANDROID_HOME/build-tools/27.0.3aaptapksignerdx
What’s in an APK?
APK ≈ JAR ≈ Zip
APKMETA_INF/ APK metadata
APKMETA_INF/lib/ Native libs
APKMETA_INF/lib/res/ Static resources(PNGs, XML layouts, etc.)
APKMETA_INF/lib/res/assets/ Static assets(fonts, HTML, etc.)
APKMETA_INF/lib/res/assets/AndroidManifest.xml Hey, this looks familiar!
APKMETA_INF/lib/res/assets/AndroidManifest.xmlclasses.dex Your code
APKMETA_INF/lib/res/assets/AndroidManifest.xmlclasses.dexresources.arsc Compiled resources(strings, dimens, etc.)
Dex?
Code(.c, etc)Machinecode
Code(.c, etc)Machine code(arm)Machine code(x86)Machine code(mips)
Java
Java(.java)Bytecode(.class)Machinecode
Java(.java)Bytecode(.class)MachinecodeAhead-of-time
Java(.java)Bytecode(.class)MachinecodeJust in time
Android
Ahead-of-timeJava(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)
Just-in-timeJava(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)Dalvik
Ahead-of-timeJava(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)ART
Ahead-of-time(on-device)Java(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)ART
Ahead-of-time(on-device)(with JIT)Java(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)ART
CompileTransformPackage
CompileTransformPackage.java à .class
CompileTransformPackage.classà .dex
CompileTransformPackage everything à .apk
Shift fromgeneric tools toAndroid-specifictools
incrementalityparallelism
GradleThe orchestrator
By defaultGradledoes nothing
Pluginsaddfunctionality
apply plugin: 'com.android.application' Android functionality
apply plugin: 'com.android.application'apply plugin: 'java' Java functionality
apply plugin: 'com.android.application'apply plugin: 'java'apply plugin: 'kotlin' Kotlin functionality
Plugins canextend the DSL
Plugins canadd dependencyconfigurations
Plugins canadd tasks
Android Plugin 3.x&Gradle 4.x
compileConfigurations
compiletestCompileConfigurations
compiletestCompiledebugCompileConfigurations
compiletestCompiledebugCompileapkConfigurations
compiletestCompiledebugCompileapkprovidedConfigurations
api Available at compile timeand runtimeConfigurations
apiimplementationAvailable at compile time,Only available toconsumers at runtimeConfigurations
apiimplementationcompileOnlyOnly available atcompile timeConfigurations
apiimplementationcompileOnlyruntimeOnlyOnly available atruntimeConfigurations
Lib B Lib A Appcompile ':libB'
Lib B Lib A Appimplemenation ':libB'
And so muchmore
Compile.java à .class
Before we compile…
Code GenerationDaggerButterknifeDatabinding
buildConfigField "String", "FOO", '"bar"'
resValue "string", "FOO", "bar"
Compilejavac / kotlinc
Transforms.class à .dex
Java 8bytecodeJava 6/7bytecode
Java 8bytecodeJava 6/7bytecodeBytecodeOptimizedbytecode
Java 8bytecodeJava 6/7bytecodeBytecodeOptimizedbytecodeJavabytecodeDex bytecode
import com.android.build.api.transform.Transform
import com.android.build.api.transform.Transformclass RetrolambdaTransform : Transform {}
app/build├── generated├── intermediates│ ├── classes│ └── transforms│ ├── dex[...]│ ├── mergeJavaRes│ ├── profilers-transform│ └── proguard└── outputs└── apk
DX and D8The dexing duo
DX is thecurrent dexing tool
$ javac Main.java$ dx --dex --output=. Main.class
dexdump lets youdisassemble dex files
$ dexdump –d classes.dex
[000148] Main.main(String)0000: sget-object v0, System;.out:PrintStream;0002: const-string v1, "Hello World"0004: invoke-virtual {v0, v1}, println:(String)V0007: return-void
D8 is thenext-gen dexing tool
Faster compilation!
Faster compilation!Smaller dex files!
Faster compilation!Smaller dex files!R8 integration!
gradle.propertiesandroid.enableD8=true
Default in Studio+ Gradle Plugin 3.1
DesugarArtificial Java sweetener
Retrolambda
RetrolambdaJack
RetrolambdaJackDesugar
RetrolambdaJackDesugarD8
Jack and JillDead tools
Shrink + ObfsucateProGuard and R8
ActivityClass A Class B
ActivityClass A
AB
ProGuardThe old guard
ProGuard is an open-sourceJava shrinker, obfuscation,and optimization tool
minifyEnabled trueproguardFiles 'proguard-rules.pro'
-keep class com.model.ImportantData { *; }
-keep class * extends android.view.View {(...);}
AAPTautomatically generatesProGuard rules forActivities
AAPTautomatically generatesProGuard rules forViews
AAPTautomatically generatesProGuard rules forServices
AAPTautomatically generatesProGuard rules forContentProviders
AAPTautomatically generatesProGuard rules forBroadcastReceivers
ActivityDrawable Class A
Drawable Class A
R8The new (pro)guard
R8The new (pro)guardAnd D8
R8 doesfull programShrinking, obfuscation,and optimization
Better incremental builds!
Better incremental builds!New DSL!
Not available yet :(
PackageMaking the APK
AAPT
AndroidAssetPackagingTool
AAPT packages,reads, and updatesAPKs
AAPT also…
AAPT also…Processes resources
AAPT also…Processes resourcesGenerates R class
AAPT also…Processes resourcesGenerates R classCompiles resources
AAPT2Android Asset Packaging Tool 2
AAPT2 is enabled bydefault as ofplugin 3.0.0
AAPT2 splitlinking and compilation
AAPT2 ismore restrictive
APK Signing
V1 signatures usejarsigner
V2 signatures useapksigner
Whole-file signaturehttps://source.android.com/security/apksigning/v2
Gradle Plugin 2.2+defaults to v2 signatures
Zipalign
Zipalign aligns APKson 4-byte boundaries
Memory CPU
Memory CPUData
MemoryCPU
MemoryCPUData
V1 signature: After signingV2 signature: Before signing
apkzlib
Packing toolsaapt apksignerzipalign
Packing toolsaapt apksignerzipalignGradle Android Pluginapkzlib
Post-build
ARTAndroid Runtime
Ahead-of-time(on-device)(with JIT)Java(.java)Bytecode(.class)MachinecodeDex Bytecode(.dex)
Compiled APK(.dex)
Compiled APK(.dex)optimize(dex2oat) OptimizedAPK(.dex, .oat)
Compiled APK(.dex)optimize(dex2oat) OptimizedAPK(.dex, .oat)JIT Profile
Compiled APK(.dex)optimize(dex2oat) OptimizedAPK(.dex, .oat)JIT Profileoptimize(dex2oat)Optimized.oat
Compiled APK(.dex)optimize(dex2oat) OptimizedAPK(.dex, .oat)JIT Profileoptimize(dex2oat)Optimized.oatAndroid 5.0
Compiled APK(.dex)optimize(dex2oat) OptimizedAPK(.dex, .oat)JIT Profileoptimize(dex2oat)Optimized.oatAndroid 7.0
State of the ART
State of the ARTInterpreted (.dex)
State of the ARTInterpreted (.dex)JIT Compiled (in memory)
State of the ARTInterpreted (.dex)JIT Compiled (in memory)AOT compiled (.oat)
Tools: android.googlesource.com/platform/tools/baseART, APK Signing: source.android.com/R8 + D8: r8.googlesource.com
https://goo.gl/cMsvmf@bryancherbst