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 25
• 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 = "25.4.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.1
+--- project :yammer-data
| --- com.squareup.retrofit:retrofit:1.9.0
| --- com.google.code.gson:gson:2.3.1 -> 2.8.1
+--- com.microsoft.aad:adal:1.12.0
| --- com.google.code.gson:gson:2.2.4 -> 2.8.1
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 {
api 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 English only
android {
defaultConfig {

resConfigs "en"

}

}
Trimming the Resources - ResConfig
android {
defaultConfig {

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

}

}
Using “resConfigs” to keep multiple languages
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 "/META-INF/*.kotlin_module"

exclude "**/kotlin/**"

exclude "**/*.properties"

exclude "**/*.xml"

exclude "**/*.txt"

}

}
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>
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.com

More Related Content

What's hot

Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
confluent
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeper
ryanlecompte
 
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
 
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
 
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
 
Developing with the Go client for Apache Kafka
Developing with the Go client for Apache KafkaDeveloping with the Go client for Apache Kafka
Developing with the Go client for Apache Kafka
Joe Stein
 
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
 
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
 
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
 
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
 
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
 
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.
 
Introduction to Apache ZooKeeper
Introduction to Apache ZooKeeperIntroduction to Apache ZooKeeper
Introduction to Apache ZooKeeper
knowbigdata
 
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More! Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis Labs
 
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
 
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin BostPulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
StreamNative
 
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!デベロッパーネットワーク
 
Hadoop security
Hadoop securityHadoop security
Hadoop security
shrey mehrotra
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
Andrus Adamchik
 

What's hot (20)

Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeper
 
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
 
Compliance as Code with terraform-compliance
Compliance as Code with terraform-complianceCompliance as Code with terraform-compliance
Compliance as Code with terraform-compliance
 
DevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on KubernetesDevoxxUK: Optimizating Application Performance on Kubernetes
DevoxxUK: Optimizating Application Performance on Kubernetes
 
Developing with the Go client for Apache Kafka
Developing with the Go client for Apache KafkaDeveloping with the Go client for Apache Kafka
Developing with the Go client for Apache Kafka
 
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
 
Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28Openstack meetup lyon_2017-09-28
Openstack meetup lyon_2017-09-28
 
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"
 
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
 
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
 
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
 
Introduction to Apache ZooKeeper
Introduction to Apache ZooKeeperIntroduction to Apache ZooKeeper
Introduction to Apache ZooKeeper
 
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More! Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
Redis in a Multi Tenant Environment–High Availability, Monitoring & Much More!
 
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
 
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin BostPulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
Pulsar Architectural Patterns for CI/CD Automation and Self-Service_Devin Bost
 
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
 
Hadoop security
Hadoop securityHadoop security
Hadoop security
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
 

Similar to The Road To Single Dex (Gradle Summit 2017)

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
 
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
 
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
 
DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2
Vincent Mercier
 
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
 
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
 
Developer workflow with docker
Developer workflow with dockerDeveloper workflow with docker
Developer workflow with docker
Wyn B. Van Devanter
 
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
 
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
 
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
 
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
 
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
 
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Daniel Gallego Vico
 

Similar to The Road To Single Dex (Gradle Summit 2017) (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
 
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)
 
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
 
DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2
 
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
 
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
 
Developer workflow with docker
Developer workflow with dockerDeveloper workflow with docker
Developer workflow with docker
 
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
 
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
 
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
 
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...
 
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...
 
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
Droidcon Spain 2105 - One app to rule them all: Methodologies, Tools & Tricks...
 

Recently uploaded

Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
aymanquadri279
 
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
 
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise EditionWhy Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Envertis Software Solutions
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
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
 
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
 
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
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
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
 
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
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
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
 

Recently uploaded (20)

Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
 
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...
 
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise EditionWhy Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
Why Choose Odoo 17 Community & How it differs from Odoo 17 Enterprise Edition
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
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
 
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
 
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
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
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
 
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
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
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
 

The Road To Single Dex (Gradle Summit 2017)

  • 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 25 • 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 = "25.4.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.1 +--- project :yammer-data | --- com.squareup.retrofit:retrofit:1.9.0 | --- com.google.code.gson:gson:2.3.1 -> 2.8.1 +--- com.microsoft.aad:adal:1.12.0 | --- com.google.code.gson:gson:2.2.4 -> 2.8.1
  • 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 { api 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 English only android { defaultConfig {
 resConfigs "en"
 }
 }
  • 43. Trimming the Resources - ResConfig android { defaultConfig {
 resConfigs "en", "de", "fr"
 }
 } Using “resConfigs” to keep multiple languages
  • 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 "/META-INF/*.kotlin_module"
 exclude "**/kotlin/**"
 exclude "**/*.properties"
 exclude "**/*.xml"
 exclude "**/*.txt"
 }
 }
  • 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. 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)
  • 58. 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)
  • 59. Optimized Results 60.8k+ < 64k DEX limit = 1 DEX file! Debug Release Method Count 100k+ 60.8k APK Size 10.1MB+ 7.1MB
  • 60. 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%
  • 61. Automating Dex Count Plugin gradle.taskGraph.whenReady { taskGraph ->
 if (taskGraph.hasTask(":assembleRelease")) {
 dexcount {
 maxMethodCount = 61000 // 61k methods
 }
 }
 } github.com/KeepSafe/dexcount-gradle-plugin
  • 62. 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