Slide 1

Slide 1 text

Reducing APK size Christophe Beyls GDG Brussels

Slide 2

Slide 2 text

Why reduce the APK size? - Faster download times and less consumed data. (slow connections, costly/limited data fees) - Smaller install size on the device. (most entry-level phones only have 8 Gb of storage)

Slide 3

Slide 3 text

Also... Less bytecode means - Faster application startup (classloader). Especially when avoiding multidex. - Much smaller install size on the device. Lollipop & Marshmallow install size = 3-4x apk size - Faster installation on Lollipop & Marshmallow.

Slide 4

Slide 4 text

Inside an APK file - classes.dex: application bytecode. Sometimes more than one file (multidex). - lib/: folder with native libraries. Optional. - res/: folder with resources files. Images + binary XML files. (layouts, selector drawables, menus, anims, …) - resources.arsc: compiled resources tables - strings, colors, dimens, styles, ids. Uncompressed for faster access.

Slide 5

Slide 5 text

APK Analyzer in Android Studio 2.2

Slide 6

Slide 6 text

classes.dex

Slide 7

Slide 7 text

1. Optimize your dependencies Never include the full version of Google Play Services. dependencies { compile 'com.google.android.gms:play-services:9.0.2' } Only declare the modules you need. dependencies { compile 'com.google.android.gms:play-services-maps:9.0.2' compile 'com.google.android.gms:play-services-location:9.0.2' compile 'com.google.android.gms:play-services-gcm:9.0.2' }

Slide 8

Slide 8 text

1. Optimize your dependencies Choose lighter libraries. www.methodscount.com Example Dex Size: - Picasso 2.5.2 106 KB - Glide 3.7.0 403 KB - Fresco 0.9.0 1483 KB If possible, avoid libraries requiring large native binaries (.so files). Examples: Fresco, Realm.

Slide 9

Slide 9 text

1. Optimize your dependencies ./gradlew [app]:dependencies

Slide 10

Slide 10 text

2. Use Proguard for release builds android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile(‘proguard-android. txt'), 'proguard-rules.pro' } } } - Big apps: multidex for debug, Proguard for release. - Add Proguard rules (if any) for each library you’re using. Many libraries already include Proguard rules inside their .aar file. - Avoid using reflection in your code. Else, add Proguard rules for it.

Slide 11

Slide 11 text

2. Use Proguard for release builds “I can’t read my stack traces anymore” 1. Lazy: add Proguard rule -dontobfuscate 2. Better: upload [app]/build/outputs/mapping/release/mapping.txt to Google Play Developer Console

Slide 12

Slide 12 text

lib/

Slide 13

Slide 13 text

If your app includes native binaries (.so files) 3. Split APK by CPU architecture Create one APK file for each CPU architecture. android { ... splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'mips' universalApk false } } }

Slide 14

Slide 14 text

res/

Slide 15

Slide 15 text

4. Remove unused resource files Very useful to remove unused parts of libraries. Requires Proguard. android { buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android. txt'), 'proguard-rules.pro' } } }

Slide 16

Slide 16 text

5. Optimize images - Manually optimize PNG (and JPEG) files using tools like Mac OS X: ImageOptim Linux: Trimage Windows: FileOptimizer. - Then disable automatic PNG optimization. Because it makes already optimized files bigger (issue 65335). android { aaptOptions { cruncherEnabled false } }

Slide 17

Slide 17 text

5. Optimize images - Replace JPEG files with lossy WebP files (Android 4+). Same quality, 33% smaller file size. - Replace small PNG icons with Vector Drawables and enable full VectorDrawable support in the support library 23.2+: android { defaultConfig { vectorDrawables.useSupportLibrary = true } } - More image optimizations: medium.com/@duhroach

Slide 18

Slide 18 text

resources.arsc

Slide 19

Slide 19 text

6. Remove unsupported locales - Libraries like AppCompat or Google Play Services include many strings in 75+ languages. - Specify the locales you support, the build tool will remove the rest. - Expect gaining a few hundred kilobytes. android { defaultConfig { ... resConfigs "en", "fr", "nl" } }

Slide 20

Slide 20 text

Thanks for watching @BladeCoder plus.google.com/+ChristopheBeyls