SlideShare a Scribd company logo
Jared Burrows
The Road to Single
Dex
Jared Burrows
Motivation
• Yammer is a social networking service used for
communication within an organization
• 3 APKs: Min SDK 15, 16 and 19, Target SDK 26
• Loading extra DEX files may lead to possible ANRs
• Multidex makes very large memory allocation requests may
crash during run time
Focus
• Reducing DEX method count
• Reducing APK size
Results
1 DEX file, Smaller APK, All features kept!
Before After Reduction
Method Count 85k+ 60.8k 28.47%
APK Size 10.7MB+ 7.1MB 33.64%
What makes an APK so big?


Multiple DEX files
+
Many Resources
What is inside an APK?
• AndroidManifest.xml
• assets/
• classes.dex
• META-INF/

- CERT.SF

- MANIFEST.MF

- CERT.RSA
• lib/
• res/

- drawable/

- layout/
• resources.arsc
Big APKs - DEX size
• Remove all/any dead code
• Remove any old/unused libraries
• Refactor out large/non-mobile libraries
• Verify Gradle configurations
Big APKs - Resources
• Remove extra and unused files in your “/res” folder
• Remove extra and used files in your “/assets” folder
Before Optimizations - Debug build
$ gradlew countDebugDexMethods sizeDebugApk



> Task :countDebugDexMethods

Total methods in debug.apk: 113007 (172.44% used) 

Total fields in debug.apk: 50547 (77.13% used) 

Methods remaining in debug.apk: 0 

Fields remaining in debug.apk: 14988



> Task :sizeDebugApk

Total APK Size in debug.apk in bytes: 12386152 (12.3MB)
Before Optimizations - Release build
$ gradlew countReleaseDexMethods sizeReleaseApk (with Proguard)



> Task :countReleaseDexMethods

Total methods in release.apk: 85259 (130.10% used) 

Total fields in release.apk: 39887 (60.86% used) 

Methods remaining in release.apk: 0 

Fields remaining in release.apk: 25648



> Task :sizeReleaseApk

Total APK Size in release.apk in bytes: 10764242 (10.7MB)
Baselined Results
85k+ > 64k DEX limit = 2 DEX files
Debug Release
Method Count 113k+ 85k+
APK Size 12.3MB+ 10.7MB+
Optimizing the DEX size
Trimming the DEX size - Dead Code
• Remove any and all unused code

- PMD - Comes with Gradle

- Proguard - Comes with Android Gradle Plugin

- Intellij/Android Studio Inspections - Click “Analyze” > Click “Inspect Code…”
• Remove all unused libraries

- We chose HockeyApp over an open source analytics library called ApplicationInsights

- HockeyApp’s functionality encompasses all of the functionality that we need from
ApplicationInsights
Trimming the DEX size - Old Libraries
• Remove old libraries

- Using HockeyApp for releasing versioning/nightlies - Allowed us to remove AndroidQuery - version
checking
• Remove unnecessary libraries

- Try not add libraries that duplicate Android’s existing functionality

- Able to remove Apache Commons validator - validate emails addresses
• Removing differential versions of same library

- Jackson 1 and Jackson 2 are the same library but Jackson 2 has a different package name

- Duplicating functionality across across prevent tools such as Proguard from optimizing
Trimming the DEX size - Transitive Libraries
• Watch out for Library Duplication

- Jackson 1 vs Jackson 2 vs Gson

- Consider using a Groovy map in your build.gradle
• Bringing in extra libraries based on a libraries’ dependencies

- Use “gradlew dependencies” to see what you are actually using
Trimming the DEX size - Transitive Libraries
ext {

supportLibraryVersion = "27.0.0"

}



ext.deps = [

"design" : "com.android.support:design:$supportLibraryVersion",

"recyclerviewV7" : "com.android.support:recyclerview-v7:$supportLibraryVersion",

"appcompatV7" : "com.android.support:appcompat-v7:$supportLibraryVersion",

"cardviewV7" : "com.android.support:cardview-v7:$supportLibraryVersion"

]
dependencies {

compile deps.design

}
Keep track of dependencies, Enforce versions
Trimming the DEX size - Transitive Libraries
gradlew dependencies --configuration compile*
compile - Classpath for compiling the main sources.
+--- project :yammer-common
| --- com.google.code.gson:gson:2.8.2
+--- project :yammer-data
| --- com.squareup.retrofit:retrofit:1.9.0
| --- com.google.code.gson:gson:2.3.1 -> 2.8.2
+--- com.microsoft.aad:adal:1.12.0
| --- com.google.code.gson:gson:2.2.4 -> 2.8.2
Trimming the DEX size - Large Libraries
• Try not to use Large/Non-mobile libraries

- Guava - 15k+ methods

- Jackson2 2.9.0.pr3 - 12k+ methods

- Check size of libraries with methodscount.com
• Necessary Evils

- AppCompat - 25.4.0 has 16.5k+ methods, 26.0.0-beta2 has 18.3k+ (continues to increase)

- Google Play Services GCM 11.0.0 - 16.7k+ methods

- Simply using both App Compat + Play Services together brings your APK to 30k+ methods,
halfway to the 64k limit per DEX file!
Trimming the DEX size - MethodsCount
methodscount.com/?lib=com.android.support:appcompat-v7:24.2.1
Trimming the DEX size - Gradle Configurations
dependencies {
compile project(":common")

compile project(":common-test")

}
Pre Android Gradle Plugin 3.0
Trimming the DEX size - Gradle Configurations
dependencies {
compile project(":common")

compile project(":common-test")

}
Pre Android Gradle Plugin 3.0
Trimming the DEX size - Gradle Configurations
Pre Android Gradle Plugin 3.0
dependencies {
compile project(":common")

testCompile project(":common-test")

}
Trimming the DEX size - Gradle Configurations
dependencies {
implementation project(":common")

testImplementation project(":common-test")

}
With Android Gradle Plugin 3.0
Trimming the DEX size - Proguard
• Use Proguard on Release builds

- Set “minifyEnabled” to true!

- Easiest way to help lower your DEX size
• Consider using “proguard-android-optimize.txt” over
“proguard-android.txt”

- Proguard will make 5 optimization passes on your code
Trimming the DEX size - Proguard
android {

buildTypes {

release {

minifyEnabled true

proguardFile getDefaultProguardFile("proguard-android.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Make sure you turn on “minifyEnabled”
Trimming the DEX size - Proguard
android {

buildTypes {

release {

minifyEnabled true

proguardFile getDefaultProguardFile("proguard-android.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Make sure you turn on “minifyEnabled”
Trimming the DEX size - Proguard
Make sure you provide Proguard rules
android {

buildTypes {

release {

minifyEnabled true

proguardFile getDefaultProguardFile("proguard-android.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Trimming the DEX size - Proguard
Try using more aggressive Proguard rules
android {

buildTypes {

release {

minifyEnabled true

proguardFile getDefaultProguardFile("proguard-android-optimize.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Trimming the DEX size - Proguard
• Remove extra Proguard rules
• Keep them up to date with the current libraries in your app
• Make sure to use “-keep” sparingly
Trimming the DEX size - Proguard
Over using “-keep” can be costly
-keep class okhttp3.* { ; }

-keep interface okhttp3.* { ; }

-dontwarn okhttp3.**

-dontnote okhttp3.**
Trimming the DEX size - Proguard
Over using “-keep” can be costly
-keep class okhttp3.* { ; }

-keep interface okhttp3.* { ; }

-dontwarn okhttp3.**

-dontnote okhttp3.**
Trimming the DEX size - Proguard
Try and let Proguard decide
-dontwarn okhttp3.**

-dontnote okhttp3.**
Optimizing the Resources
Trimming the Resources - Lint
• Make sure to use lint to check for “UnusedResources”
• Do not suppress this lint rule unless you are writing an
Android library
• Consider failing the builds based on lint warnings/errors
Trimming the Resources - Lint
Strict lint options
android {

lintOptions {

textReport true

textOutput "stdout"

checkAllWarnings true

warningsAsErrors true

}

}
Trimming the Resources - Lint
android {

lintOptions {

error "UnusedResources"

}

}
Less strict, check for “UnusedResources”
Trimming the Resources - ShrinkResources
• What Lint does not find, you have to remove manually
• Remove all unused resources in “assets/” folder

- Raw media such as Font files
• Use “shrinkResources” to remove unused resources

- Great for removing library dependencies resources in your final APK
Trimming the Resources - ShrinkResources
android {

buildTypes {

release {

minifyEnabled true

proguardFile getDefaultProguardFile("proguard-android-optimize.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Missing “shrinkResources”
Trimming the Resources - ShrinkResources
Added “shrinkResources”
android {

buildTypes {

release {

minifyEnabled true
shrinkResources true

proguardFile getDefaultProguardFile("proguard-android-optimize.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Trimming the Resources - ShrinkResources
Using “shrinkResources”
android {

buildTypes {

release {

minifyEnabled true
shrinkResources true

proguardFile getDefaultProguardFile("proguard-android-optimize.txt")

proguardFile "custom-proguard-rules.txt"

signingConfig signingConfigs.release

}

}

}

Trimming the Resources - ResConfigs
• Use “resConfigs” to filter out localizations that you do not
want/support in your app
Trimming the Resources - ResConfig
Using “resConfigs” to keep multiple resources or languages
android {
defaultConfig {
resConfigs "en"
}
}
Trimming the Resources - ResConfig
Using “resConfigs” to keep multiple languages
android {
defaultConfig {

resConfigs "en","de","fr"

}

}
Trimming the Resources - PackagingOptions
• Remove extra files that are baked into your APK
• Use the APK Analyzer to find these files

- In Android Studio, Click “Build” > Click “Analyze APK…”
• Use “packagingOptions” to filter out these files
Trimming the Resources - PackagingOptions
android {

packagingOptions {

exclude "META-INF/LICENSE.txt"

exclude "META-INF/NOTICE.txt"

}

}
Common “packagingOptions” excludes
Trimming the Resources - PackagingOptions
After using common “packagingOptions” excludes
Trimming the Resources - PackagingOptions
Strict “packagingOptions” excludes
android {

packagingOptions {

exclude "**/*.kotlin_module"
exclude "**/*.version"

exclude "**/kotlin/**"

exclude "**/*.xml"

exclude “**/*.txt"
exclude "**/*.properties"

}

}
Trimming the Resources - PackagingOptions
After using stricter “packagingOptions” excludes
Trimming the Resources - Vector Drawables
• Consider converting simple PNGs to “Vector” Drawables
• Single XML file is smaller than multiple PNGs
• Use tools such as “svg2android” to convert SVGs to Android
Vector Drawables
Trimming the Resources - Vector Drawables
android {

defaultConfig {

resConfigs "en", "de", "fr"

vectorDrawables {

useSupportLibrary = true

}

}

}
Using “vectorDrawables.useSupportLibrary = true” to prevent PNG generation
Trimming the Resources - Vector Drawables
android {

defaultConfig {

resConfigs "en", "de", "fr"

vectorDrawables {

useSupportLibrary = true

}

}

}
Using “vectorDrawables.useSupportLibrary = true” to prevent PNG generation
Trimming the Resources - Vector Drawables
inloop.github.io/svg2android/
Trimming the Resources - Vector Drawables
After dropping your SVG file, Copy it to your project in “res/drawable”
Trimming the Resources - Vector Drawables
Make sure to use “app:srcCompat” your in XML
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">



<ImageView

android:layout_width="30dp"

android:layout_height="30dp"

android:src="@drawable/circle"/>



<ImageView

android:layout_width="25dp"

android:layout_height="25dp"

android:src="@drawable/hello"/>

</LinearLayout>
Trimming the Resources - Vector Drawables
Make sure to use “app:srcCompat” your in XML
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">



<ImageView

android:layout_width="30dp"

android:layout_height="30dp"

android:src="@drawable/circle"/>



<ImageView

android:layout_width="25dp"

android:layout_height="25dp"

android:src="@drawable/hello"/>

</LinearLayout>
Trimming the Resources - Vector Drawables
Using “app:srcCompat” your in XML
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">



<ImageView

android:layout_width="30dp"

android:layout_height="30dp"

app:srcCompat="@drawable/circle"/>



<ImageView

android:layout_width="25dp"

android:layout_height="25dp"

app:srcCompat="@drawable/hello"/>

</LinearLayout>
Trimming the Resources - WebP
• Reduces image sizes by converting to WebP
• Does not need to compress at build time(PNG crunching)
• By converting beforehand, this will help speed up your build
Trimming the Resources - WebP
Right-click on “drawable” folders, click on “Convert to WebP”
After Optimizations - Debug build
$ gradlew countDebugDexMethods sizeDebugApk



> Task :countDebugDexMethods

Total methods in debug.apk: 100595 (153.50% used) 

Total fields in debug.apk: 51278 (78.25% used) 

Methods remaining in debug.apk: 0 

Fields remaining in debug.apk: 14257



> Task :sizeDebugApk

Total APK Size in debug.apk in bytes: 10053036 (10.1MB)
After Optimizations - Release build
$ gradlew countReleaseDexMethods sizeReleaseApk (with Proguard)



> Task :countReleaseDexMethods

Total methods in release.apk: 60810 (92.79% used) 

Total fields in release.apk: 29445 (44.93% used) 

Methods remaining in release.apk: 4725

Fields remaining in release.apk: 36090



> Task :sizeReleaseApk

Total APK Size in release.apk in bytes: 7049930 (7.1MB)
Optimized Results
60.8k+ < 64k DEX limit = 1 DEX file!
Debug Release
Method Count 100k+ 60.8k
APK Size 10.1MB+ 7.1MB
Before vs After Release Builds
1 DEX file, Smaller APK, All features kept!
Before After Reduction
Method Count 85k+ 60.8k 28.47%
APK Size 10.7MB+ 7.1MB 33.64%
Automating Dex Count Plugin
gradle.taskGraph.whenReady { taskGraph ->

if (taskGraph.hasTask(":assembleRelease")) {

dexcount {

maxMethodCount = 61000 // 61k methods

}

}

}
github.com/KeepSafe/dexcount-gradle-plugin
Automating APK Size Plugin
gradle.taskGraph.whenReady { taskGraph ->

if (taskGraph.hasTask(":assembleRelease")) {

apkSize {

maxApkSize = 8000 // in Kb

}

}

}
github.com/vanniktech/gradle-android-apk-size-plugin
Thank you! Questions?
twitter.com/jaredsburrows
github.com/jaredsburrows
jaredsburrows@gmail.com
jaredsburrows.com

More Related Content

What's hot

Going Serverless with Java - a real life story
Going Serverless with Java - a real life storyGoing Serverless with Java - a real life story
Going Serverless with Java - a real life story
Herman Lintvelt
 
Compliance as Code with terraform-compliance
Compliance as Code with terraform-complianceCompliance as Code with terraform-compliance
Compliance as Code with terraform-compliance
Emre Erkunt
 
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated HadoopHadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
Yafang Chang
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeper
ryanlecompte
 
DevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on KubernetesDevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on Kubernetes
Dinakar Guniguntala
 
Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28
Xavier Lucas
 
OpenStack APIs: Present and Future (Beta Talk)
OpenStack APIs: Present and Future (Beta Talk)OpenStack APIs: Present and Future (Beta Talk)
OpenStack APIs: Present and Future (Beta Talk)
Wade Minter
 
Optimizing {Java} Application Performance on Kubernetes
Optimizing {Java} Application Performance on KubernetesOptimizing {Java} Application Performance on Kubernetes
Optimizing {Java} Application Performance on Kubernetes
Dinakar Guniguntala
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
IT Event
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
Shu-Jeng Hsieh
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
Mykyta Protsenko
 
Running High Performance & Fault-tolerant Elasticsearch Clusters on Docker
Running High Performance & Fault-tolerant Elasticsearch Clusters on DockerRunning High Performance & Fault-tolerant Elasticsearch Clusters on Docker
Running High Performance & Fault-tolerant Elasticsearch Clusters on Docker
Sematext Group, Inc.
 
Creating PostgreSQL-as-a-Service at Scale
Creating PostgreSQL-as-a-Service at ScaleCreating PostgreSQL-as-a-Service at Scale
Creating PostgreSQL-as-a-Service at Scale
Sean Chittenden
 
Get Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAMGet Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAM
Jonathan Katz
 
Introduction to Apache ZooKeeper
Introduction to Apache ZooKeeperIntroduction to Apache ZooKeeper
Introduction to Apache ZooKeeper
knowbigdata
 
Hadoop security
Hadoop securityHadoop security
Hadoop security
shrey mehrotra
 
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheConTechnical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
Yahoo!デベロッパーネットワーク
 
Elasticsearch for Logs & Metrics - a deep dive
Elasticsearch for Logs & Metrics - a deep diveElasticsearch for Logs & Metrics - a deep dive
Elasticsearch for Logs & Metrics - a deep dive
Sematext Group, Inc.
 
Safely Protect PostgreSQL Passwords - Tell Others to SCRAM
Safely Protect PostgreSQL Passwords - Tell Others to SCRAMSafely Protect PostgreSQL Passwords - Tell Others to SCRAM
Safely Protect PostgreSQL Passwords - Tell Others to SCRAM
Jonathan Katz
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
Andrus Adamchik
 

What's hot (20)

Going Serverless with Java - a real life story
Going Serverless with Java - a real life storyGoing Serverless with Java - a real life story
Going Serverless with Java - a real life story
 
Compliance as Code with terraform-compliance
Compliance as Code with terraform-complianceCompliance as Code with terraform-compliance
Compliance as Code with terraform-compliance
 
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated HadoopHadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
HadoopCon2015 Multi-Cluster Live Synchronization with Kerberos Federated Hadoop
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeper
 
DevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on KubernetesDevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on Kubernetes
 
Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28
 
OpenStack APIs: Present and Future (Beta Talk)
OpenStack APIs: Present and Future (Beta Talk)OpenStack APIs: Present and Future (Beta Talk)
OpenStack APIs: Present and Future (Beta Talk)
 
Optimizing {Java} Application Performance on Kubernetes
Optimizing {Java} Application Performance on KubernetesOptimizing {Java} Application Performance on Kubernetes
Optimizing {Java} Application Performance on Kubernetes
 
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
Leonid Vasilyev  "Building, deploying and running production code at Dropbox"Leonid Vasilyev  "Building, deploying and running production code at Dropbox"
Leonid Vasilyev "Building, deploying and running production code at Dropbox"
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
 
Running High Performance & Fault-tolerant Elasticsearch Clusters on Docker
Running High Performance & Fault-tolerant Elasticsearch Clusters on DockerRunning High Performance & Fault-tolerant Elasticsearch Clusters on Docker
Running High Performance & Fault-tolerant Elasticsearch Clusters on Docker
 
Creating PostgreSQL-as-a-Service at Scale
Creating PostgreSQL-as-a-Service at ScaleCreating PostgreSQL-as-a-Service at Scale
Creating PostgreSQL-as-a-Service at Scale
 
Get Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAMGet Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAM
 
Introduction to Apache ZooKeeper
Introduction to Apache ZooKeeperIntroduction to Apache ZooKeeper
Introduction to Apache ZooKeeper
 
Hadoop security
Hadoop securityHadoop security
Hadoop security
 
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheConTechnical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
Technical tips for secure Apache Hadoop cluster #ApacheConAsia #ApacheCon
 
Elasticsearch for Logs & Metrics - a deep dive
Elasticsearch for Logs & Metrics - a deep diveElasticsearch for Logs & Metrics - a deep dive
Elasticsearch for Logs & Metrics - a deep dive
 
Safely Protect PostgreSQL Passwords - Tell Others to SCRAM
Safely Protect PostgreSQL Passwords - Tell Others to SCRAMSafely Protect PostgreSQL Passwords - Tell Others to SCRAM
Safely Protect PostgreSQL Passwords - Tell Others to SCRAM
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
 

Similar to The Road To Single Dex (GDG San Francisco Meetup)

Generating efficient APK by Reducing Size and Improving Performance
Generating efficient APK by Reducing Size and Improving PerformanceGenerating efficient APK by Reducing Size and Improving Performance
Generating efficient APK by Reducing Size and Improving Performance
Paresh Mayani
 
AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018 AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018
Theerasan Tonthongkam
 
Android Applications Development: A Quick Start Guide
Android Applications Development: A Quick Start GuideAndroid Applications Development: A Quick Start Guide
Android Applications Development: A Quick Start Guide
Sergii Zhuk
 
CNIT 128 6. Analyzing Android Applications (Part 1)
CNIT 128 6. Analyzing Android Applications (Part 1)CNIT 128 6. Analyzing Android Applications (Part 1)
CNIT 128 6. Analyzing Android Applications (Part 1)
Sam Bowne
 
DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2
Vincent Mercier
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
Michael Lange
 
Optimize APK size
Optimize APK sizeOptimize APK size
Optimize APK size
Kirill Rozov
 
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
Codemotion
 
Developer workflow with docker
Developer workflow with dockerDeveloper workflow with docker
Developer workflow with docker
Wyn B. Van Devanter
 
Decrease build time and application size
Decrease build time and application sizeDecrease build time and application size
Decrease build time and application size
Keval Patel
 
Containers Roadshow: How to Develop Containers for the Enterprise
Containers Roadshow: How to Develop Containers for the EnterpriseContainers Roadshow: How to Develop Containers for the Enterprise
Containers Roadshow: How to Develop Containers for the Enterprise
Honza Horák
 
Android Introduction
Android IntroductionAndroid Introduction
Android Introduction
aswapnal
 
Creating Developer-Friendly Docker Containers with Chaperone
Creating Developer-Friendly Docker Containers with ChaperoneCreating Developer-Friendly Docker Containers with Chaperone
Creating Developer-Friendly Docker Containers with Chaperone
Gary Wisniewski
 
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
Felipe Prado
 
Android dev tips
Android dev tipsAndroid dev tips
Android dev tips
Kanda Runapongsa Saikaew
 
TIAD 2016 : Application delivery in a container world
TIAD 2016 : Application delivery in a container worldTIAD 2016 : Application delivery in a container world
TIAD 2016 : Application delivery in a container world
The Incredible Automation Day
 
C++ Windows Forms L01 - Intro
C++ Windows Forms L01 - IntroC++ Windows Forms L01 - Intro
C++ Windows Forms L01 - Intro
Mohammad Shaker
 
DCEU 18: Developing with Docker Containers
DCEU 18: Developing with Docker ContainersDCEU 18: Developing with Docker Containers
DCEU 18: Developing with Docker Containers
Docker, Inc.
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Patrick Chanezon
 
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
Alexandre Gouaillard
 

Similar to The Road To Single Dex (GDG San Francisco Meetup) (20)

Generating efficient APK by Reducing Size and Improving Performance
Generating efficient APK by Reducing Size and Improving PerformanceGenerating efficient APK by Reducing Size and Improving Performance
Generating efficient APK by Reducing Size and Improving Performance
 
AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018 AndroidX Google Extended I/O BKK 2018
AndroidX Google Extended I/O BKK 2018
 
Android Applications Development: A Quick Start Guide
Android Applications Development: A Quick Start GuideAndroid Applications Development: A Quick Start Guide
Android Applications Development: A Quick Start Guide
 
CNIT 128 6. Analyzing Android Applications (Part 1)
CNIT 128 6. Analyzing Android Applications (Part 1)CNIT 128 6. Analyzing Android Applications (Part 1)
CNIT 128 6. Analyzing Android Applications (Part 1)
 
DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
 
Optimize APK size
Optimize APK sizeOptimize APK size
Optimize APK size
 
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
To ∞ (~65K) and beyond! - Sebastiano Gottardo - Codemotion Milan 2016
 
Developer workflow with docker
Developer workflow with dockerDeveloper workflow with docker
Developer workflow with docker
 
Decrease build time and application size
Decrease build time and application sizeDecrease build time and application size
Decrease build time and application size
 
Containers Roadshow: How to Develop Containers for the Enterprise
Containers Roadshow: How to Develop Containers for the EnterpriseContainers Roadshow: How to Develop Containers for the Enterprise
Containers Roadshow: How to Develop Containers for the Enterprise
 
Android Introduction
Android IntroductionAndroid Introduction
Android Introduction
 
Creating Developer-Friendly Docker Containers with Chaperone
Creating Developer-Friendly Docker Containers with ChaperoneCreating Developer-Friendly Docker Containers with Chaperone
Creating Developer-Friendly Docker Containers with Chaperone
 
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
 
Android dev tips
Android dev tipsAndroid dev tips
Android dev tips
 
TIAD 2016 : Application delivery in a container world
TIAD 2016 : Application delivery in a container worldTIAD 2016 : Application delivery in a container world
TIAD 2016 : Application delivery in a container world
 
C++ Windows Forms L01 - Intro
C++ Windows Forms L01 - IntroC++ Windows Forms L01 - Intro
C++ Windows Forms L01 - Intro
 
DCEU 18: Developing with Docker Containers
DCEU 18: Developing with Docker ContainersDCEU 18: Developing with Docker Containers
DCEU 18: Developing with Docker Containers
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
 
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
 

Recently uploaded

SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 

Recently uploaded (20)

SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 

The Road To Single Dex (GDG San Francisco Meetup)

  • 1. Jared Burrows The Road to Single Dex Jared Burrows
  • 2. Motivation • Yammer is a social networking service used for communication within an organization • 3 APKs: Min SDK 15, 16 and 19, Target SDK 26 • Loading extra DEX files may lead to possible ANRs • Multidex makes very large memory allocation requests may crash during run time
  • 3. Focus • Reducing DEX method count • Reducing APK size
  • 4. Results 1 DEX file, Smaller APK, All features kept! Before After Reduction Method Count 85k+ 60.8k 28.47% APK Size 10.7MB+ 7.1MB 33.64%
  • 5. What makes an APK so big? 
 Multiple DEX files + Many Resources
  • 6. What is inside an APK? • AndroidManifest.xml • assets/ • classes.dex • META-INF/
 - CERT.SF
 - MANIFEST.MF
 - CERT.RSA • lib/ • res/
 - drawable/
 - layout/ • resources.arsc
  • 7. Big APKs - DEX size • Remove all/any dead code • Remove any old/unused libraries • Refactor out large/non-mobile libraries • Verify Gradle configurations
  • 8. Big APKs - Resources • Remove extra and unused files in your “/res” folder • Remove extra and used files in your “/assets” folder
  • 9. Before Optimizations - Debug build $ gradlew countDebugDexMethods sizeDebugApk
 
 > Task :countDebugDexMethods
 Total methods in debug.apk: 113007 (172.44% used) 
 Total fields in debug.apk: 50547 (77.13% used) 
 Methods remaining in debug.apk: 0 
 Fields remaining in debug.apk: 14988
 
 > Task :sizeDebugApk
 Total APK Size in debug.apk in bytes: 12386152 (12.3MB)
  • 10. Before Optimizations - Release build $ gradlew countReleaseDexMethods sizeReleaseApk (with Proguard)
 
 > Task :countReleaseDexMethods
 Total methods in release.apk: 85259 (130.10% used) 
 Total fields in release.apk: 39887 (60.86% used) 
 Methods remaining in release.apk: 0 
 Fields remaining in release.apk: 25648
 
 > Task :sizeReleaseApk
 Total APK Size in release.apk in bytes: 10764242 (10.7MB)
  • 11. Baselined Results 85k+ > 64k DEX limit = 2 DEX files Debug Release Method Count 113k+ 85k+ APK Size 12.3MB+ 10.7MB+
  • 13. Trimming the DEX size - Dead Code • Remove any and all unused code
 - PMD - Comes with Gradle
 - Proguard - Comes with Android Gradle Plugin
 - Intellij/Android Studio Inspections - Click “Analyze” > Click “Inspect Code…” • Remove all unused libraries
 - We chose HockeyApp over an open source analytics library called ApplicationInsights
 - HockeyApp’s functionality encompasses all of the functionality that we need from ApplicationInsights
  • 14. Trimming the DEX size - Old Libraries • Remove old libraries
 - Using HockeyApp for releasing versioning/nightlies - Allowed us to remove AndroidQuery - version checking • Remove unnecessary libraries
 - Try not add libraries that duplicate Android’s existing functionality
 - Able to remove Apache Commons validator - validate emails addresses • Removing differential versions of same library
 - Jackson 1 and Jackson 2 are the same library but Jackson 2 has a different package name
 - Duplicating functionality across across prevent tools such as Proguard from optimizing
  • 15. Trimming the DEX size - Transitive Libraries • Watch out for Library Duplication
 - Jackson 1 vs Jackson 2 vs Gson
 - Consider using a Groovy map in your build.gradle • Bringing in extra libraries based on a libraries’ dependencies
 - Use “gradlew dependencies” to see what you are actually using
  • 16. Trimming the DEX size - Transitive Libraries ext {
 supportLibraryVersion = "27.0.0"
 }
 
 ext.deps = [
 "design" : "com.android.support:design:$supportLibraryVersion",
 "recyclerviewV7" : "com.android.support:recyclerview-v7:$supportLibraryVersion",
 "appcompatV7" : "com.android.support:appcompat-v7:$supportLibraryVersion",
 "cardviewV7" : "com.android.support:cardview-v7:$supportLibraryVersion"
 ] dependencies {
 compile deps.design
 } Keep track of dependencies, Enforce versions
  • 17. Trimming the DEX size - Transitive Libraries gradlew dependencies --configuration compile* compile - Classpath for compiling the main sources. +--- project :yammer-common | --- com.google.code.gson:gson:2.8.2 +--- project :yammer-data | --- com.squareup.retrofit:retrofit:1.9.0 | --- com.google.code.gson:gson:2.3.1 -> 2.8.2 +--- com.microsoft.aad:adal:1.12.0 | --- com.google.code.gson:gson:2.2.4 -> 2.8.2
  • 18. Trimming the DEX size - Large Libraries • Try not to use Large/Non-mobile libraries
 - Guava - 15k+ methods
 - Jackson2 2.9.0.pr3 - 12k+ methods
 - Check size of libraries with methodscount.com • Necessary Evils
 - AppCompat - 25.4.0 has 16.5k+ methods, 26.0.0-beta2 has 18.3k+ (continues to increase)
 - Google Play Services GCM 11.0.0 - 16.7k+ methods
 - Simply using both App Compat + Play Services together brings your APK to 30k+ methods, halfway to the 64k limit per DEX file!
  • 19. Trimming the DEX size - MethodsCount methodscount.com/?lib=com.android.support:appcompat-v7:24.2.1
  • 20. Trimming the DEX size - Gradle Configurations dependencies { compile project(":common")
 compile project(":common-test")
 } Pre Android Gradle Plugin 3.0
  • 21. Trimming the DEX size - Gradle Configurations dependencies { compile project(":common")
 compile project(":common-test")
 } Pre Android Gradle Plugin 3.0
  • 22. Trimming the DEX size - Gradle Configurations Pre Android Gradle Plugin 3.0 dependencies { compile project(":common")
 testCompile project(":common-test")
 }
  • 23. Trimming the DEX size - Gradle Configurations dependencies { implementation project(":common")
 testImplementation project(":common-test")
 } With Android Gradle Plugin 3.0
  • 24. Trimming the DEX size - Proguard • Use Proguard on Release builds
 - Set “minifyEnabled” to true!
 - Easiest way to help lower your DEX size • Consider using “proguard-android-optimize.txt” over “proguard-android.txt”
 - Proguard will make 5 optimization passes on your code
  • 25. Trimming the DEX size - Proguard android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFile getDefaultProguardFile("proguard-android.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }
 Make sure you turn on “minifyEnabled”
  • 26. Trimming the DEX size - Proguard android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFile getDefaultProguardFile("proguard-android.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }
 Make sure you turn on “minifyEnabled”
  • 27. Trimming the DEX size - Proguard Make sure you provide Proguard rules android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFile getDefaultProguardFile("proguard-android.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }

  • 28. Trimming the DEX size - Proguard Try using more aggressive Proguard rules android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFile getDefaultProguardFile("proguard-android-optimize.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }

  • 29. Trimming the DEX size - Proguard • Remove extra Proguard rules • Keep them up to date with the current libraries in your app • Make sure to use “-keep” sparingly
  • 30. Trimming the DEX size - Proguard Over using “-keep” can be costly -keep class okhttp3.* { ; }
 -keep interface okhttp3.* { ; }
 -dontwarn okhttp3.**
 -dontnote okhttp3.**
  • 31. Trimming the DEX size - Proguard Over using “-keep” can be costly -keep class okhttp3.* { ; }
 -keep interface okhttp3.* { ; }
 -dontwarn okhttp3.**
 -dontnote okhttp3.**
  • 32. Trimming the DEX size - Proguard Try and let Proguard decide -dontwarn okhttp3.**
 -dontnote okhttp3.**
  • 34. Trimming the Resources - Lint • Make sure to use lint to check for “UnusedResources” • Do not suppress this lint rule unless you are writing an Android library • Consider failing the builds based on lint warnings/errors
  • 35. Trimming the Resources - Lint Strict lint options android {
 lintOptions {
 textReport true
 textOutput "stdout"
 checkAllWarnings true
 warningsAsErrors true
 }
 }
  • 36. Trimming the Resources - Lint android {
 lintOptions {
 error "UnusedResources"
 }
 } Less strict, check for “UnusedResources”
  • 37. Trimming the Resources - ShrinkResources • What Lint does not find, you have to remove manually • Remove all unused resources in “assets/” folder
 - Raw media such as Font files • Use “shrinkResources” to remove unused resources
 - Great for removing library dependencies resources in your final APK
  • 38. Trimming the Resources - ShrinkResources android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFile getDefaultProguardFile("proguard-android-optimize.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }
 Missing “shrinkResources”
  • 39. Trimming the Resources - ShrinkResources Added “shrinkResources” android {
 buildTypes {
 release {
 minifyEnabled true shrinkResources true
 proguardFile getDefaultProguardFile("proguard-android-optimize.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }

  • 40. Trimming the Resources - ShrinkResources Using “shrinkResources” android {
 buildTypes {
 release {
 minifyEnabled true shrinkResources true
 proguardFile getDefaultProguardFile("proguard-android-optimize.txt")
 proguardFile "custom-proguard-rules.txt"
 signingConfig signingConfigs.release
 }
 }
 }

  • 41. Trimming the Resources - ResConfigs • Use “resConfigs” to filter out localizations that you do not want/support in your app
  • 42. Trimming the Resources - ResConfig Using “resConfigs” to keep multiple resources or languages android { defaultConfig { resConfigs "en" } }
  • 43. Trimming the Resources - ResConfig Using “resConfigs” to keep multiple languages android { defaultConfig {
 resConfigs "en","de","fr"
 }
 }
  • 44. Trimming the Resources - PackagingOptions • Remove extra files that are baked into your APK • Use the APK Analyzer to find these files
 - In Android Studio, Click “Build” > Click “Analyze APK…” • Use “packagingOptions” to filter out these files
  • 45. Trimming the Resources - PackagingOptions android {
 packagingOptions {
 exclude "META-INF/LICENSE.txt"
 exclude "META-INF/NOTICE.txt"
 }
 } Common “packagingOptions” excludes
  • 46. Trimming the Resources - PackagingOptions After using common “packagingOptions” excludes
  • 47. Trimming the Resources - PackagingOptions Strict “packagingOptions” excludes android {
 packagingOptions {
 exclude "**/*.kotlin_module" exclude "**/*.version"
 exclude "**/kotlin/**"
 exclude "**/*.xml"
 exclude “**/*.txt" exclude "**/*.properties"
 }
 }
  • 48. Trimming the Resources - PackagingOptions After using stricter “packagingOptions” excludes
  • 49. Trimming the Resources - Vector Drawables • Consider converting simple PNGs to “Vector” Drawables • Single XML file is smaller than multiple PNGs • Use tools such as “svg2android” to convert SVGs to Android Vector Drawables
  • 50. Trimming the Resources - Vector Drawables android {
 defaultConfig {
 resConfigs "en", "de", "fr"
 vectorDrawables {
 useSupportLibrary = true
 }
 }
 } Using “vectorDrawables.useSupportLibrary = true” to prevent PNG generation
  • 51. Trimming the Resources - Vector Drawables android {
 defaultConfig {
 resConfigs "en", "de", "fr"
 vectorDrawables {
 useSupportLibrary = true
 }
 }
 } Using “vectorDrawables.useSupportLibrary = true” to prevent PNG generation
  • 52. Trimming the Resources - Vector Drawables inloop.github.io/svg2android/
  • 53. Trimming the Resources - Vector Drawables After dropping your SVG file, Copy it to your project in “res/drawable”
  • 54. Trimming the Resources - Vector Drawables Make sure to use “app:srcCompat” your in XML <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <ImageView
 android:layout_width="30dp"
 android:layout_height="30dp"
 android:src="@drawable/circle"/>
 
 <ImageView
 android:layout_width="25dp"
 android:layout_height="25dp"
 android:src="@drawable/hello"/>
 </LinearLayout>
  • 55. Trimming the Resources - Vector Drawables Make sure to use “app:srcCompat” your in XML <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <ImageView
 android:layout_width="30dp"
 android:layout_height="30dp"
 android:src="@drawable/circle"/>
 
 <ImageView
 android:layout_width="25dp"
 android:layout_height="25dp"
 android:src="@drawable/hello"/>
 </LinearLayout>
  • 56. Trimming the Resources - Vector Drawables Using “app:srcCompat” your in XML <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <ImageView
 android:layout_width="30dp"
 android:layout_height="30dp"
 app:srcCompat="@drawable/circle"/>
 
 <ImageView
 android:layout_width="25dp"
 android:layout_height="25dp"
 app:srcCompat="@drawable/hello"/>
 </LinearLayout>
  • 57. Trimming the Resources - WebP • Reduces image sizes by converting to WebP • Does not need to compress at build time(PNG crunching) • By converting beforehand, this will help speed up your build
  • 58. Trimming the Resources - WebP Right-click on “drawable” folders, click on “Convert to WebP”
  • 59. After Optimizations - Debug build $ gradlew countDebugDexMethods sizeDebugApk
 
 > Task :countDebugDexMethods
 Total methods in debug.apk: 100595 (153.50% used) 
 Total fields in debug.apk: 51278 (78.25% used) 
 Methods remaining in debug.apk: 0 
 Fields remaining in debug.apk: 14257
 
 > Task :sizeDebugApk
 Total APK Size in debug.apk in bytes: 10053036 (10.1MB)
  • 60. After Optimizations - Release build $ gradlew countReleaseDexMethods sizeReleaseApk (with Proguard)
 
 > Task :countReleaseDexMethods
 Total methods in release.apk: 60810 (92.79% used) 
 Total fields in release.apk: 29445 (44.93% used) 
 Methods remaining in release.apk: 4725
 Fields remaining in release.apk: 36090
 
 > Task :sizeReleaseApk
 Total APK Size in release.apk in bytes: 7049930 (7.1MB)
  • 61. Optimized Results 60.8k+ < 64k DEX limit = 1 DEX file! Debug Release Method Count 100k+ 60.8k APK Size 10.1MB+ 7.1MB
  • 62. Before vs After Release Builds 1 DEX file, Smaller APK, All features kept! Before After Reduction Method Count 85k+ 60.8k 28.47% APK Size 10.7MB+ 7.1MB 33.64%
  • 63. Automating Dex Count Plugin gradle.taskGraph.whenReady { taskGraph ->
 if (taskGraph.hasTask(":assembleRelease")) {
 dexcount {
 maxMethodCount = 61000 // 61k methods
 }
 }
 } github.com/KeepSafe/dexcount-gradle-plugin
  • 64. Automating APK Size Plugin gradle.taskGraph.whenReady { taskGraph ->
 if (taskGraph.hasTask(":assembleRelease")) {
 apkSize {
 maxApkSize = 8000 // in Kb
 }
 }
 } github.com/vanniktech/gradle-android-apk-size-plugin