Slide 1

Slide 1 text

1

Slide 2

Slide 2 text

The disclaimer. @nisrulz 2

Slide 3

Slide 3 text

The story. @nisrulz 3

Slide 4

Slide 4 text

What happened ● April 4, 2018 ● Trying to build a Android Project ○ Typical project ○ Multi module ○ Native code (NDK) ○ Common dependencies: Retrofit, Dagger, Rx, Support Libraries, etc 4 @nisrulz

Slide 5

Slide 5 text

What happened ● April 4, 2018 ● Trying to build a Android Project ○ Typical project ○ Multi module ○ Native code (NDK) ○ Common dependencies: Retrofit, Dagger, Rx, Support Libraries, etc ● Laptop: Macbook Air (early 2014) Core i5, 4 GB RAM, 128 GB SSD 5 @nisrulz

Slide 6

Slide 6 text

What happened 6 @nisrulz

Slide 7

Slide 7 text

What happened My build times: ~37 minutes 7 @nisrulz

Slide 8

Slide 8 text

What happened My build times: ~37 minutes Not just the first time, but every other build after that too. 8 @nisrulz

Slide 9

Slide 9 text

What I tried With a few gradle tweaks in the project Build times down to ~28 minutes 9 @nisrulz

Slide 10

Slide 10 text

What I tried After exhausting all possibilities 10 @nisrulz

Slide 11

Slide 11 text

What I tried After exhausting all possibilities Switched to Terminal builds and VS Code. 11 @nisrulz +

Slide 12

Slide 12 text

12 @nisrulz +

Slide 13

Slide 13 text

What I tried The result 13 @nisrulz +

Slide 14

Slide 14 text

What I tried The result Build times down to ~3 minutes (89% reduction) 14 @nisrulz +

Slide 15

Slide 15 text

15 @nisrulz How I reduced my Android build times by 89%

Slide 16

Slide 16 text

The experience. @nisrulz 16

Slide 17

Slide 17 text

The experience State of speed: Slow 17 @nisrulz

Slide 18

Slide 18 text

The experience State of reliability: Finicky 18 @nisrulz

Slide 19

Slide 19 text

The experience State of reliability: Finicky 19 @nisrulz

Slide 20

Slide 20 text

The experience State of choice selection: ● Forced ● Deviates from its base: IntelliJ IDE 20 @nisrulz

Slide 21

Slide 21 text

The experience State of new tools: Limited ● Profilers 21 @nisrulz

Slide 22

Slide 22 text

The experience State of new tools: Limited ● Profilers ● Constraint Layout Editor 22 @nisrulz

Slide 23

Slide 23 text

The experience State of memory consumption: 23 @nisrulz

Slide 24

Slide 24 text

The experience State of memory consumption: 24 @nisrulz

Slide 25

Slide 25 text

The experience State of CPU consumption: 25 @nisrulz

Slide 26

Slide 26 text

The experience State of CPU consumption: 26 @nisrulz

Slide 27

Slide 27 text

The experience State of updates/versions: 27 @nisrulz

Slide 28

Slide 28 text

The experience To summarize, Android Studio is ● Slow ● Finicky ● Forces its defaults and deviates from its base ● New tools are limiting as in are Android Studio specific ○ Profilers ○ Constraint Layout Editor ● Uses a lot of Memory and CPU ● Has versioning problem (Stable, Beta, Alpha) 28 @nisrulz

Slide 29

Slide 29 text

is slow. @nisrulz 29

Slide 30

Slide 30 text

Slow, but why? ● Gradle Configuration ● Indexing changes in code ● Plugins ● Code Insight: Inplace analysis/inspections 30 @nisrulz

Slide 31

Slide 31 text

Configuring Gradle for speed Use the latest Gradle release. 31 @nisrulz Incremental compile 1000-module Java project https://gradle.org/whats-new/gradle-5/

Slide 32

Slide 32 text

Configuring Gradle for speed Use the latest Gradle release. Caveat: Update to latest Canary release of Android Studio, since the support for latest Gradle is tied to Android Studio. 32 @nisrulz

Slide 33

Slide 33 text

Configuring Gradle for speed Build Cache: Reuse outputs from any previous invocation of Gradle // Add this in your global gradle.properties file // at ~/.gradle/gradle.properties // Enable Build Cache android.enableBuildCache=true 33 @nisrulz

Slide 34

Slide 34 text

Configuring Gradle for speed Daemon: Dedicated background process to improve performance of Gradle // Add this in your global gradle.properties file // at ~/.gradle/gradle.properties // Enable Gradle Daemon org.gradle.daemon=true 34 @nisrulz

Slide 35

Slide 35 text

Configuring Gradle for speed Allocate memory: Increase the memory provided to JVM // Add this in your global gradle.properties file // at ~/.gradle/gradle.properties // Configure allocated memory org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m 35 @nisrulz

Slide 36

Slide 36 text

Configuring Gradle for speed Parallel builds: Force Gradle to execute tasks in parallel as long as those tasks are in different projects. // Add this in your global gradle.properties file // at ~/.gradle/gradle.properties // Enable Parallel builds org.gradle.parallel=true 36 @nisrulz

Slide 37

Slide 37 text

Reducing Indexing If your codebase has files changing on each build, it will trigger indexing. Suggestions: ● Avoid using annotation processors ● Using implementation as much as possible, instead of api. ● Use static build config values i.e version code, version name, resources 37 @nisrulz

Slide 38

Slide 38 text

Plugins: Inspect what you use Android Studio comes with a lot of Plugins enabled, which contribute to its sluggishness. 38 @nisrulz

Slide 39

Slide 39 text

Plugins: Inspect what you use Android Studio comes with a lot of Plugins enabled, which contribute to its sluggishness. Solution: Check and disable what you don’t need. 39 @nisrulz

Slide 40

Slide 40 text

Code Insight Although required, it does make Android Studio slow. Solution: Enable Power Save Mode 40 @nisrulz

Slide 41

Slide 41 text

Terminal to the rescue. @nisrulz 41

Slide 42

Slide 42 text

ADB: Android Debug Bridge ● Command Line tool ● Shipped with Android SDK ● Allows interacting with debuggable Android devices ● Client-Server program ● Available as: adb 42 @nisrulz

Slide 43

Slide 43 text

ADB: Android Debug Bridge ● Install App adb install path_to_apk ● Uninstall App adb uninstall com.package.name ● Copy a file from System to Android device adb push path_to_file /path_to_dir_on_device ● Copy a file from Android device to System adb pull /path_to_dir_on_device/file.png ~/path_on_system/ 43 @nisrulz

Slide 44

Slide 44 text

Other tools via ADB shell ● Activity Manager: am ● Emulator: emulator ● Package Manager: pm ● Device Policy Manager: dpm ● Logcat: logcat ● Dumpsys: dumpsys and many more. 44 @nisrulz

Slide 45

Slide 45 text

Gradle Android projects use Gradle as the build system. Each Android project has a gradle wrapper, which is a proxy to local Gradle binary. Android Studio invokes Gradle to execute tasks The same can be done via terminal: ./gradlew assembleDebug > is equivalent to Make in Android studio 45 @nisrulz

Slide 46

Slide 46 text

Lint This is part of the gradle tasks, which checks the code for structural inconsistencies, thus allowing to write more maintainable code. // Execute lint in project ./gradlew lint > Similar to executing via Android Studio 46 @nisrulz

Slide 47

Slide 47 text

Lint 47 @nisrulz

Slide 48

Slide 48 text

Scrcpy https://github.com/Genymobile/scrcpy Command-line tool for mirroring and controlling your device. // Start mirroring the device scrcpy //Record while mirroring scrcpy --record file.mp4 // Show touches scrcpy --show-touches // Switch off screen scrcpy --turn-screen-off 48 @nisrulz

Slide 49

Slide 49 text

Classyshark https://github.com/google/android-classyshark Tool for decompiling and analyzing internals of an APK such as dex Count. Works with .apk, .jar, .aar, .class, .dex or .so files. Execute: java -jar ClassyShark.jar 49 @nisrulz

Slide 50

Slide 50 text

Classyshark 50 @nisrulz

Slide 51

Slide 51 text

Classyshark 51 @nisrulz

Slide 52

Slide 52 text

Detekt https://github.com/arturbosch/detekt ● Static code analyzer for Kotlin language. ● Helps to detect code smell in kotlin codebase ● Highly configurable ● Enables complexity analysis of the code ● Also has a gradle plugin to setup in the project // Execute at the root of the project java -jar /path_to/detekt-cli.jar --debug 52 @nisrulz

Slide 53

Slide 53 text

Detekt // Execute at the root of the project java -jar /path_to/detekt-cli.jar --debug // Output Complexity Report: - 686 lines of code (loc) - 563 source lines of code (sloc) - 425 logical lines of code (lloc) - 32 comment lines of code (cloc) ... - 218 code smells per 1000 lloc Project Statistics: - number of properties: 73 - number of functions: 22 - number of classes: 5 - number of packages: 3 - number of kt files: 5 53 @nisrulz

Slide 54

Slide 54 text

AVD Manager ● Command line tool to create and manage Android Virtual Devices (AVD) ● Located in android_sdk/tools/bin/ // List all avd avdmanager list // Create a new avd avdmanager create avd -n myavd -k "system-images;android-29;google_apis;x86" // Remove avd avdmanager delete avd -n myavd 54 @nisrulz

Slide 55

Slide 55 text

SDK Manager ● Command line tool to manage Android SDK ● Used to view, install, remove packages in Android SDK ● Located in android_sdk/tools/bin/ // List all available packages sdkmanager --list // Install packages sdkmanager packages // Remove packages sdkmanager --uninstall packages // Update all packages sdkmanager --update 55 @nisrulz

Slide 56

Slide 56 text

Battery Historian https://github.com/google/battery-historian ● Python based tool ● Used to inspect battery related information and events, while the device was not plugged in ● For Android device running Android 5.0 Lollipop (API level 21) and later. ● Useful since the new Energy Profilers are Android Studio only. 56 @nisrulz

Slide 57

Slide 57 text

Battery Historian 57 @nisrulz

Slide 58

Slide 58 text

Battery Historian 58 @nisrulz

Slide 59

Slide 59 text

IntelliJ Idea ● Android Studio is based on IntelliJ Idea ○ IntelliJ Idea can be used for Android Development ● Faster for development ● Consumes less memory/CPU than Android Studio ● Full plugin support ● More frequent updates ● Doesn’t have the Android Studio specific tools ○ Constraint Layout Editor ○ Profilers ○ New project structure dialog 59 @nisrulz

Slide 60

Slide 60 text

Automation ● Alias creation enables executing complex tool configuration as a simple command. Example: // Create alias to push release apk to Downloads folder in Device alias pushReleaseToDevice="adb push ./apk-release.apk /sdcard/Downloads" // Execute pushReleaseToDevice ↵ 60 @nisrulz

Slide 61

Slide 61 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # Install APK to device # Use as: apkinstall app-debug.apk alias apkinstall="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X install -r $1" # As an alternative to apkinstall, you can also do just ./gradlew installDebug # Alias for building and installing the apk to connected device # Run at the root of your project # $ buildAndInstallApk alias buildAndInstallApk='./gradlew assembleDebug && apkinstall ./app/build/outputs/apk/debug/app-debug.apk' 61 @nisrulz

Slide 62

Slide 62 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # Launch your debug apk on your connected device # Execute at the root of your android project # Usage: launchDebugApk alias launchDebugApk="adb shell monkey -p `aapt dump badging ./app/build/outputs/apk/debug/app-debug.apk | grep -e 'package: name' | cut -d \' -f 2` 1" # ------------- Single command to build+install+launch apk------------# # Execute at the root of your android project # Use as: buildInstallLaunchDebugApk alias buildInstallLaunchDebugApk="buildAndInstallApk && launchDebugApk" 62 @nisrulz

Slide 63

Slide 63 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # Take screenshot alias screenshot="adb exec-out screencap -p > screen-$(date -j "+%s").png" # Remove app alias rmapp="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X uninstall $1" # Clear data for app alias clearapp="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X shell pm clear $1" More automation aliases: https://gist.github.com/nisrulz/b0e79f2b3e27f99ca8b5dba9db6281ec 63 @nisrulz

Slide 64

Slide 64 text

Automation ● Use gradle plugin to setup all the automation commands Novoda’s Gradle Android command plugin creates handy gradle tasks in the project itself. https://github.com/novoda/gradle-android-command-plugin Some commands available: ● installDevice - installs the app on a specific device. ● uninstallDevice - uninstalls the app from a specific device. ● run - installs and launches the app on a specific device. and many more. Execute: ./gradlew installDeviceDebug 64 @nisrulz

Slide 65

Slide 65 text

The experience. @nisrulz 65

Slide 66

Slide 66 text

The experience ● Project Marble Project Marble is a multi-release and focused effort on making fundamental features of the IDE rock-solid and polished. It is ongoing effort. Already made improvements under: 1. UX and performance in Layout Editor 2. Instant Run has been replaced by Apply Changes 3. Emulator performance, Snapshots 4. Lint performance 66 @nisrulz

Slide 67

Slide 67 text

The experience ● APK Analyzer GUI in Android Studio 67 @nisrulz

Slide 68

Slide 68 text

The experience ● APK Analyzer GUI in Android Studio + Command-line tool Enables anyone to use it outside Android Studio // To print the file size of the apk in a human readable format; Output: 1.7MB 68 @nisrulz

Slide 69

Slide 69 text

The experience ● APK Analyzer // Prints the application ID, version code, and version name. // Output: in.excogitation.deviceinfo 17 2.0.1 apkanalyzer apk summary myapp.apk // Prints an estimate of the download size of the APK. // Output: 1.4MB apkanalyzer -h apk download-size myapp.apk ● More info: https://developer.android.com/studio/command-line/apkanalyzer 69 @nisrulz

Slide 70

Slide 70 text

Links/References Gradle Performance Tips: https://guides.gradle.org/performance/ Project Marble: https://medium.com/androiddevelopers/tagged/project-marble Blog Post: https://android.jlelse.eu/how-i-reduced-my-android-build-times-by-89-4242e51ce946 Disable Plugins: https://www.reddit.com/r/androiddev/comments/7sxhig/android_studio_slower_when_using_kotlin/dt88 pgn/ Battery Historian: https://developer.android.com/studio/profile/battery-historian 70 @nisrulz

Slide 71

Slide 71 text

Credits Icon made by Freepik from www.flaticon.com 71 @nisrulz

Slide 72

Slide 72 text

twitter.com/nisrulz github.com/nisrulz www.nisrulz.com 72

Slide 73

Slide 73 text

twitter.com/nisrulz github.com/nisrulz www.nisrulz.com 73