This is the presentation of the talk I gave in the MAD meetup on 15th April. This talk basically explains different tricks & tweaks to decrease your application size and your Gradle build time.
If you have any queries or any feedback, hit me on twitter: https://twitter.com/kevalpatel2106
Android Application Components with Implementation & Examples
Decrease build time and application size
1. Decrease build time and
application size by 60%
Keval Patel
Android Developer @multidots
1
2. Agenda
- What is Gradle? How does it work?
- Why decrease application build time?
- How to decrease application build time?
- Introduction to APK analyzer
- Why is APK size so important?
- How to trim your APK?
2
3. What is Gradle?
- Very powerful build system - Written in Groovy & Java
- Open source
- Flexible dependency management
- Task based
3
4. What Gradle does?
- Building .dx files from java source.
- Merge all the resources and assets.
- Generates .apk from the source
code.
4
6. Why you should care about your build time?
Let’s say,
- You are generating 15 clean builds every day.
- Each build takes 3 minutes to generate.
- Total time: 15 * 3 = 45 mins.
- If you work for 8 hours a day, that’s almost 10% of your work time.
- That’s about 4 hours a week !!!
6
8. Benchmarking with I/O’16 Application
- Open source (https://github.com/google/iosched)
- 25+ dependencies and third party libraries
- 41538 method references
8
9. - Two modules:
- android: Contains android application classes and resources.
- server: Contains codebase for backend server.
- Minimum SDK - 16
- Target SDK - 22/23
- 9 different languages
Benchmarking with I/O’16 Application
9
10. Gradle build life cycle
1. Initialization 2. Configuration 3. Execution
- Initialize resources
- Start daemon thread
- Figure out what to build
- Evaluate your
build.gradle script
- Configure all the plugins
- Evaluate the task graph.
- Runs all the
previously
evaluated task
- Build the
application. 10
11. --profile will tell gradle to measure the time taken to execute each task and
dump that data into HTML file.
--profile your gradle build time
$ ./gradlew assembleDebug
You can find that report under /[your project dir]/build/reports/profile
directory.
Sample
11
--profile
14. - --dry-run tells gradle to evaluate the project but don’t run any task.
- The last phase of the life cycle (execution phase) won’t get executed.
- Tells us the time required by Gradle to configure the project and to start
the build.
Measure time required to configure
14
18. Gradle Daemon
- Gradle runs on the Java Virtual Machine (JVM) and uses several supporting libraries
to be load at initialization time. That's why it's slow to start.
More info : https://docs.gradle.org/current/userguide/gradle_daemon.html
- Gradle Daemon is a long-lived process that will run in the background.
- Avoid the cost of JVM startup for every build,
- Able to cache information about project structure, files, tasks, and more in
memory.
18
19. Commands for Gradle Daemon
- To enable daemon for gradle build use --daemon.
- To get a list of running Gradle Daemons and their statuses use the --status
command.
- To stop daemon use --stop command.
19More info : https://docs.gradle.org/current/userguide/gradle_daemon.html
20. Gradle Daemon
$ ./gradlew assembleDebug --dry-run --configure-on-demand --daemon --profile
Initialization time decreased by
4.1 seconds than before after
running the build for the second
time.
Speed improvements will apply
for subsequent builds.
20
22. Dex in the process
- “Dex in process” is a process that allows to run multiple dex processes to
run within the single VM that is also shared with the gradle.
- Requirement:
- Build tool version 23.0.2 or above.
- Android Studio 2.0 or above.
22
23. Dex in the process
- Multiple dx processes runs on
different VM instances.
- These increases build time as each
dx has to pass data between
different VM instances.
- Requires less per VM heap size as
single VM is hosting only single dx
process.
https://www.youtube.com/watch?v=-SY5nkNVUn0
23
24. Dex in the process
Starting from AS 2.0,
- All these dx processes run in the
single VM and that VM is also
shared with the gradle.
- Require higher hip size to run as
much as possible dx processes in
a single instance.
https://www.youtube.com/watch?v=-SY5nkNVUn0
24
25. Dex in the process
Add below line in your /gradle.properties file to re-configure the heap size.
org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
- Select the best suitable heap size for your system based on the amount of
RAM available.
- Generally, after 4GB, any further increase in heap size won’t affect the
build time.
25
26. Enable parallel builds
- If you have multiple modules in you project, then by enabling this, gradle
can run build operations for independent modules parallelly.
- Gradle will only build modules parallelly if two modules are not
interdependent.
Google I/O project doesn’t have multiple modules, building parallel won’t make much difference.
26
27. Enable parallel builds
Add below line in your /gradle.properties file to enable parallel builds.
org.gradle.parallel=true
27
28. Other small things to remember…
- Avoid heavy computations, like increasing the version code from git
commits count or downloading some files from URL while building the
project.
- Always use latest gradle version. (Current is 3.4.1)
- Don’t use dynamic dependency.
compile 'com.android.support:appcompat-v7:23.0.+' compile 'com.android.support:appcompat-v7:23.0.1'
28
29. TL;DR
#Enable daemon
org.gradle.daemon=true
# Try and find out the best heap size for your project build.
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Modularise your project and enable parallel build
org.gradle.parallel=true
# Enable configure on demand.
org.gradle.configureondemand=true
- Add below line in your /gradle.properties.
- Modularize your project.
29
31. Why APK size is so important?
- Because you want to get your next billion users.
- Mobile devices have limited amount of battery, limited storage, limited
processing power, limited RAM, limited internet connectivity…
- Currently, more than 11000 android devices are out in the market and
most of them are having low-end configurations.
- Two key things that are precious to every smartphone user,
1)Storage.
31
32. Storage
- Most low-mid range devices have 8GB to 16GB
internal storage.
- The less storage your application uses, the
more free space user gets to store their videos
and images.
- You don’t want your user to uninstall your
application because of “Storage out of space”
notification. 32
33. Network connectivity
- Most of the android users are from developing
countries (like India, Brazil or countries in Africa)
where they have very limited 2G/3G connectivity.
- If your application is large in size, it will take a longer
time to download the application.
- Most of the users have limited amount of data.
- Every byte user uses to download the application, will
affect your user’s wallet.
33
35. APK Analyser
Provides immediate insight into the composition of your APK.
Features:
- View file size and the download size of the APK
- View AndroidManifest.xml
- View resources
- View dex files and method counts for each dex files.
- Compare two APK files. 35
37. Breakdown of APK
- APK file mainly contains 3 major components which utilize the maximum
amount of size in whole apk package:
1.classes.dex - dex file which contains bytecode of your java classes.
2. res - Contains images, icons and raw files, menu files, and layouts.
3. resources.arsc - Holds all the value resources. This resource contains
strings, dimensions, styles, integers, view ids etc.
37
39. Proguard
- A Java class file shrinker, optimizer, obfuscator, and preverifier.
- It detects and removes unused classes, fields, methods, and attributes. It
optimizes bytecode and removes unused instructions.
- It renames the remaining classes, fields, and methods using short
meaningless names to prevent reverse engineering of your apk file.
39
40. How to apply proguard?
- You have two default proguard files bundled in your SDK that you can
apply.
- proguard-android.txt - contains light-weight proguard rules.
- proguard-android-optimize.txt - contains very aggressive obfuscation and shrinking rules.
release {
//Enable the proguard
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"
}
40
41. Let’s see the results…
Before:
After:
Size decreased from 3.1 MB to 1.98MB. (~50% decrease) 41
43. Enable “shrinkResources”
- Many unused images and strings (e.g. resources for sign in with google button
images) those are not used in your entire application.
- Most of these unused images/resources are from third party libraries (e.g.
Google Play Services).
43
44. Enable “shrinkResources”
- Remove all the resources (images/strings), those are not used anywhere in
the project.
- To enable this in your build, add below lines:
release{
//...
//...
shrinkResources true
//...
} 44
45. Set “resConfigs”
- Libraries like Google Play Services contains resources from different
locales.
- Your application does not support all locales.
- Provide the list of locales your application supports and “resConfigs” will
remove all the resources for not supported locales.
defaultConfig {
//...
//strip other than english resources
resConfigs "en"
}
45
46. Convert your png images to webp
- webp is image format like png but having less size than png image with
the same quality.
- webp is natively supported by Android since the beginning. So you can
load webp images in ImageView same as other raster images.
- Android Studio 2.3 provides a built-in tool that can convert your png
images to webp.
46
47. How to convert png images to webp?
- Right-click on the image and select
“Convert to webp”.
- Select quality of the output image.
- Select whether to convert
transparent images to webp or not.
- Hit “OK”. That’s it!!
47
49. Let’s see the results…
After:
res folder size decreased from 710KB to 597KB. (Decrease by 16%) 49
50. Final comparison
* This are the results from the current version of the Anti-Theft apk. So, numbers are different than previous slides.
50
51. TL;DR
Enable proguard in your project by adding following lines to your release
build type.
Enable “shrinkResources”.
Strip down all the unused locale resources by adding required resources
name in “resConfigs”.
Convert all the images to the webp or vector drawable.
51
52. How to decrease your Gradle build time by 65%?
http://bit.ly/2jvi9XB
How you can decrease application size by 60% (In only 5 minutes)?
http://bit.ly/2mWQQIc
52
References:
Introduction
Ahmedabad
2 years of experience
Designation
AAD
- First learn about gradle.
- Made up of two parts.
PART-1
- Why it is required to decrease build time?
- How you can decrease?
PART-2
- Basics and how to of APK analyser
- Why APK size?
- How can you decrease?
Gradle is very powerful build system.
Builds your application.
Not just for android.
We write build.gradle script.
Open source
Very flexible dependency management
Kind of plug and play.
Just write compile -----
Also, easy to add build type and product flavour
Written groovey
Nowadays java. (Display the screen shot)
Tasks are everything in gradle
assembleDebug is a task. Which depends on other tasks.
Only for android prospective
Builds .dx files from java file. Java ----> class -----> .dx
Merge all the resources based on product flavour
Complex process of generating apk.
Why?
Demonstrate simple math.
Less Build time ⇒
Less time to see gradle building your project ⇒
More time for other work ⇒
Make some bug fixes ⇒
Implement some cool features ⇒
Happy users, the ultimate goal.
Two Downside,
Less coffee
Less lunch/snack brakes.
Before we go how to decrease time….
We need some benchmarking.
We are software guys, we need proof.
If applying those tricks, decreases time really?
I/O’16 app project
Open source
Available on github.
Name on GitHub ⇒ iosched. (weird)
I/O’17 code is not available yet😊
25+ dependency
And 41K methods
Not multi dexed yet
Let’s look in basic structure,
App?
Server?
What are these modules , explain
Min sdk - 16 Android 4.1 or above.
Target SDK 23 (?Marshmallow). That was the latest while i/o 16.
9 different locales.
Phases:
Init
Set resources.
Init java instance in JVM.
Pull required resources to JVM.
Daemon thread to hold those resources.
Config
Evaluate script.
Figure out what to do? Task graph
Any plugins/external build scripts?
(com.android.application) ⇒ For application.
com.android.library ⇒ For libs module.
Exe.
Main phase.
Run all tasks
Compiles code to .dx.
Generates APK.
Sample Report : http://psychiatrist-sheep-25576.bitballoon.com
Command to generate debug apk.
--profile to create report in HTML
Always good to run gradle with this tag.
Later build time suddenly increase, provides you insight.
Out of these three only Execution phase is important.
Other two phases are useless.
How we can measure the exact time required to config?