Slide 1

Slide 1 text

2

Slide 2

Slide 2 text

The disclaimer @nisrulz 3

Slide 3

Slide 3 text

Where it started @nisrulz 4

Slide 4

Slide 4 text

What happened ● Trying to build an Android Project ○ Typical project ○ Multi module 5 @nisrulz

Slide 5

Slide 5 text

What happened ● Trying to build an Android Project ○ Native code (NDK) ○ Common dependencies: Retrofit, Dagger, Rx, Support Libraries, etc 6 @nisrulz

Slide 6

Slide 6 text

What happened ● Laptop: Macbook Air (early 2014) ○ Core i5(1.4 Ghz) ○ 4GB DDR3 RAM ○ 128GB SSD ○ Intel HD Graphics (1.5GB) 7 @nisrulz

Slide 7

Slide 7 text

What happened My build times: ~37 min 8 @nisrulz

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

What happened My build times: ~37 min …and not only that 10 @nisrulz

Slide 10

Slide 10 text

What happened ...but also 11 @nisrulz

Slide 11

Slide 11 text

What happened With a few gradle tweaks in the project. 12 @nisrulz https://guides.gradle.org/performance/

Slide 12

Slide 12 text

What happened Build times down to ~28 min With a few gradle tweaks in the project. 13 @nisrulz https://guides.gradle.org/performance/

Slide 13

Slide 13 text

What happened 14 @nisrulz After exhausting all possibilities.

Slide 14

Slide 14 text

What happened Switched to Terminal builds and VS Code Editor. 15 @nisrulz + After exhausting all possibilities.

Slide 15

Slide 15 text

What happened 16 @nisrulz +

Slide 16

Slide 16 text

What happened 17 @nisrulz + Final result.

Slide 17

Slide 17 text

What happened 18 @nisrulz + Build times down to ~3 minutes( 89% reduction) Final result.

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

20 @nisrulz I was just happy that I was not in a spot like this guy

Slide 20

Slide 20 text

The experience. @nisrulz 21

Slide 21

Slide 21 text

The experience State of speed: Slow 22 @nisrulz

Slide 22

Slide 22 text

The experience Basically this... State of speed: Slow 23 @nisrulz

Slide 23

Slide 23 text

The experience State of speed: Slow 24 @nisrulz

Slide 24

Slide 24 text

The experience State of reliability: Critical issues 25 @nisrulz

Slide 25

Slide 25 text

The experience State of reliability: Critical issues 26 @nisrulz https://issuetracker.google.com/issues/133864394

Slide 26

Slide 26 text

The experience State of reliability: Critical issues 27 @nisrulz https://issuetracker.google.com/issues/133864394

Slide 27

Slide 27 text

The experience State of reliability: Critical issues 28 @nisrulz ~3 months https://issuetracker.google.com/issues/133864394

Slide 28

Slide 28 text

The experience State of reliability: Finicky 29 @nisrulz

Slide 29

Slide 29 text

The experience State of reliability: Finicky 30 @nisrulz

Slide 30

Slide 30 text

The experience To a point where someone had to build this: A nuke script! https://github.com/rock3r/deep-clean 31 @nisrulz

Slide 31

Slide 31 text

The experience - Tweet dated: 26 July 2019 - Android Studio 3.5 Stable (released): 20 August 2019 > Was already on bleeding edge 32 @nisrulz https://twitter.com/nisrulz/status/1154760 114026532864

Slide 32

Slide 32 text

The experience 33 @nisrulz https://twitter.com/nisrulz/status/1154758411684392961

Slide 33

Slide 33 text

The experience State of polish: 34 @nisrulz https://www.reddit.com/r/androiddev/c omments/d271hc/wildly_infuriating/

Slide 34

Slide 34 text

The experience State of choice: Forced, deviates from base 35 @nisrulz

Slide 35

Slide 35 text

The experience State of memory consumption: Not suitable 36 @nisrulz

Slide 36

Slide 36 text

The experience State of memory consumption: Not suitable 37 @nisrulz

Slide 37

Slide 37 text

The experience State of memory consumption: Not suitable 38 @nisrulz

Slide 38

Slide 38 text

The experience State of CPU consumption: Unacceptable 39 @nisrulz

Slide 39

Slide 39 text

The experience State of CPU consumption: Unacceptable 40 @nisrulz

Slide 40

Slide 40 text

The experience State of updates: Unreliable 41 @nisrulz

Slide 41

Slide 41 text

The experience State of result: false-positives 42 @nisrulz

Slide 42

Slide 42 text

The experience State of result: false-positives 43 @nisrulz

Slide 43

Slide 43 text

The experience State of tools: Limited 44 @nisrulz Energy Profiler

Slide 44

Slide 44 text

The experience State of tools: Limited 45 @nisrulz Constraint Layout Editor

Slide 45

Slide 45 text

The experience State of tools: Limited 46 @nisrulz Resource Manager

Slide 46

Slide 46 text

The experience State of tools: Limited 47 @nisrulz Apply Changes

Slide 47

Slide 47 text

The experience State of tools: Limited 48 @nisrulz Apply Changes https://medium.com/androiddevelopers/android-studio-pro ject-marble-apply-changes-e3048662e8cd

Slide 48

Slide 48 text

The experience State of tools: Limited 49 @nisrulz Apply Changes https://developer.android.com/studio/known-issues#appl y-changes-ki-verification-errors

Slide 49

Slide 49 text

The experience State of tools: Limited 50 @nisrulz Deployments

Slide 50

Slide 50 text

The experience To summarize, Android Studio is ● Slow ● Finicky ● Forces its defaults and deviates from its base 51 @nisrulz

Slide 51

Slide 51 text

The experience To summarize, Android Studio is ● New tools are limiting ○ Energy Profiler ○ Constraint Layout Editor ○ Resource Manager ○ Apply Changes ○ Deployments options 52 @nisrulz

Slide 52

Slide 52 text

The experience To summarize, Android Studio is ● Uses a lot of Memory and CPU ● Has versioning quality problem (Stable, Beta, Alpha) 53 @nisrulz

Slide 53

Slide 53 text

and Workarounds. @nisrulz 54

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 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 release. 57 @nisrulz

Slide 57

Slide 57 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 58 @nisrulz

Slide 58

Slide 58 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 59 @nisrulz

Slide 59

Slide 59 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 60 @nisrulz

Slide 60

Slide 60 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 61 @nisrulz

Slide 61

Slide 61 text

Configuring Gradle for speed Execution: Prefer running specific task over general ones // Creates AAR for every module and all variants! ./gradlew assemble // Creates AAR for every module’s debug variant ./gradlew assembleDebug // Creates AAR for only `mymodule` in debug variant! ./gradlew :mymodule:assembleDebug 62 @nisrulz

Slide 62

Slide 62 text

Reducing Indexing If your codebase has files changing on each build, it will trigger indexing. 63 @nisrulz

Slide 63

Slide 63 text

Reducing Indexing Suggestions: ● Avoid using annotation processors Or use incremental annotation processors ● Using implementation as much as possible, instead of api. ● Use static build config values i.e version code, version name, resources 64 @nisrulz

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Plugins: Inspect what you use Solution: Check and disable what you don’t need. 66 @nisrulz

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

Terminal to the rescue. @nisrulz 68

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

ADB: Android Debug Bridge ● Install App ○ adb install path_to_apk ● Uninstall App ○ adb uninstall com.package.name 70 @nisrulz

Slide 70

Slide 70 text

ADB: Android Debug Bridge ● 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/ 71 @nisrulz

Slide 71

Slide 71 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. 72 @nisrulz

Slide 72

Slide 72 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 73 @nisrulz

Slide 73

Slide 73 text

Gradle The same can be done via terminal: ./gradlew assembleDebug > is equivalent to Make in Android studio 74 @nisrulz

Slide 74

Slide 74 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 75 @nisrulz

Slide 75

Slide 75 text

Lint 76 @nisrulz

Slide 76

Slide 76 text

Detekt https://github.com/arturbosch/detekt ● Static code analyzer for Kotlin language. ● Helps to detect code smell in kotlin codebase 77 @nisrulz

Slide 77

Slide 77 text

Detekt https://github.com/arturbosch/detekt ● Highly configurable ● Enables complexity analysis of the code ● Also has a gradle plugin to setup in the project 78 @nisrulz

Slide 78

Slide 78 text

Detekt https://github.com/arturbosch/detekt // Execute at the root of the project java -jar /path_to/detekt-cli.jar --debug 79 @nisrulz

Slide 79

Slide 79 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 80 @nisrulz

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

Classyshark https://github.com/google/andr oid-classyshark Execute: java -jar ClassyShark.jar 82 @nisrulz

Slide 82

Slide 82 text

Classyshark 83 @nisrulz

Slide 83

Slide 83 text

Classyshark 84 @nisrulz

Slide 84

Slide 84 text

AVD Manager ● Command line tool to create and manage Android Virtual Devices (AVD) ● Located in android_sdk/tools/bin/ 85 @nisrulz

Slide 85

Slide 85 text

AVD Manager // 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 86 @nisrulz

Slide 86

Slide 86 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 87 @nisrulz

Slide 87

Slide 87 text

Scrcpy https://github.com/Genymobile/scrcpy Command-line tool for mirroring and controlling your device. // Show touches scrcpy --show-touches // Switch off screen scrcpy --turn-screen-off 88 @nisrulz

Slide 88

Slide 88 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/ 89 @nisrulz

Slide 89

Slide 89 text

SDK Manager // List all available packages sdkmanager --list // Install packages sdkmanager packages // Remove packages sdkmanager --uninstall packages // Update all packages sdkmanager --update 90 @nisrulz

Slide 90

Slide 90 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 91 @nisrulz

Slide 91

Slide 91 text

Battery Historian https://github.com/google/battery-historian ● For Android device running Android 5.0 Lollipop (API level 21) and later. ● Useful since the new Energy Profilers are Android Studio only. 92 @nisrulz

Slide 92

Slide 92 text

Battery Historian 93 @nisrulz

Slide 93

Slide 93 text

Battery Historian 94 @nisrulz

Slide 94

Slide 94 text

IntelliJ Idea ● Android Studio is based on IntelliJ Idea ○ IntelliJ Idea can be used for Android Development ● Faster for development 95 @nisrulz

Slide 95

Slide 95 text

IntelliJ Idea ● Consumes less memory/CPU than Android Studio ● Full plugin support ● More frequent updates 96 @nisrulz

Slide 96

Slide 96 text

IntelliJ Idea ● Doesn’t have the Android Studio specific tools ○ Constraint Layout Editor ○ Profilers ○ Resource Manager ○ Apply Changes 97 @nisrulz

Slide 97

Slide 97 text

Mainframer ● Build your project remotely on a better hardware ● Uses rsync to sync changes over ssh and then builds the project, syncs the apk back. https://github.com/buildfoundation/mainframer 98 @nisrulz

Slide 98

Slide 98 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 ↵ 99 @nisrulz

Slide 99

Slide 99 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # Install APK to device # Use: apkinstall app-debug.apk alias apkinstall="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X install -r $1" 100 @nisrulz

Slide 100

Slide 100 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # 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 # Usage: buildAndInstallApk alias buildAndInstallApk='./gradlew assembleDebug && apkinstall ./app/build/outputs/apk/debug/app-debug.apk' 101 @nisrulz

Slide 101

Slide 101 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 function launchDebugApk(){ local APP_PACKAGE_NAME=$(getPackageName ./app/build/outputs/apk/debug/app-debug.apk) adb shell monkey -p $APP_PACKAGE_NAME 1 1>/dev/null 2>&1; } 102 @nisrulz

Slide 102

Slide 102 text

Automation ● Command line tools enable ability to include in scripts. Using alias simplify the process. # ------------- Single command to build+install+launch apk------------# # Execute at the root of your android project # Use as: buildInstallLaunchDebugApk alias buildInstallLaunchDebugApk="buildAndInstallApk && launchDebugApk" 103 @nisrulz

Slide 103

Slide 103 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-$(nowdate).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 104 @nisrulz

Slide 104

Slide 104 text

Automation++ ● adbe : ADB Enhanced - Script to execute adb commands on all connected devices. # Usage # Run any command you would run with adb for all the connected devices # ./adbe is the equivalent of ./adb -s # # Examples # ./adbe version ./adbe install demo_app.apk 105 @nisrulz https://github.com/nisrulz/terminal-utils/blob/master/android/adbe.sh

Slide 105

Slide 105 text

Automation++ ● adbe : ADB Enhanced // Script body adb devices | while read line do if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ] then device=`echo $line | awk '{print $1}'` echo "$device $@ ..." adb -s $device $@ fi done 106 @nisrulz

Slide 106

Slide 106 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 107 @nisrulz

Slide 107

Slide 107 text

Automation ● Use gradle plugin to setup all the automation commands 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 108 @nisrulz

Slide 108

Slide 108 text

The experience. @nisrulz 109

Slide 109

Slide 109 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. 110 @nisrulz

Slide 110

Slide 110 text

The experience ● Project Marble 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 111 @nisrulz

Slide 111

Slide 111 text

The experience ● Project Marble Issues: https://developer.android.com/studio/known-issues 112 @nisrulz

Slide 112

Slide 112 text

The experience {Command line tools} 113 @nisrulz

Slide 113

Slide 113 text

The experience ● APK Analyzer(GUI) 114 @nisrulz

Slide 114

Slide 114 text

The experience ● APK Analyzer(Command line) // To print the file size of the apk in a human readable format //Output: 1.7MB 115 @nisrulz

Slide 115

Slide 115 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 116 @nisrulz

Slide 116

Slide 116 text

The experience ● APK Analyzer // 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 117 @nisrulz

Slide 117

Slide 117 text

The experience ● APK Analyzer // Get package name of the passed apk file // Usage: getPackageName app-debug.apk alias getPackageName="apkanalyzer -h manifest application-id $1" More info: https://developer.android.com/studio/command-line/apkanalyzer 118 @nisrulz

Slide 118

Slide 118 text

The experience ● Size Analyzer // Tool to understand the size of Android application. size-analyzer check-bundle size-analyzer check-project More info: https://github.com/android/size-analyzer 119 @nisrulz

Slide 119

Slide 119 text

The experience ● Size Analyzer 120 @nisrulz

Slide 120

Slide 120 text

The experience ● Android Studio Poet // Create a real life complexity Android project that // mimics your own and observe the build times java -jar as-poet.jar MyConfig.json More info: https://github.com/android/android-studio-poet 121 @nisrulz

Slide 121

Slide 121 text

The experience ● Android Studio Poet 122 @nisrulz

Slide 122

Slide 122 text

The experience ● Simpleperf A versatile command-line CPU profiling tool included in the NDK for Mac, Linux, and Windows. 123 @nisrulz

Slide 123

Slide 123 text

The experience ● Simpleperf # Find the percentage of time spent in each thread simpleperf report --sort tid,comm # See how function calls are related, call-graph simpleperf report -g More info: https://developer.android.com/ndk/guides/simpleperf 124 @nisrulz

Slide 124

Slide 124 text

The experience ● NDK-Stack It allows you to symbolize stack traces from adb logcat It replaces any address inside a shared library with the corresponding : from your source code, making debugging easier. 125 @nisrulz

Slide 125

Slide 125 text

The experience ● NDK-Stack # Live mapping adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a More info: https://developer.android.com/ndk/guides/ndk-stack 126 @nisrulz

Slide 126

Slide 126 text

The experience ● Other tools ○ NDK-GDB: Tool to start a command-line native debugging session. ○ ASan (Address Sanitizer): Memory error detector for C/C++ 127 @nisrulz

Slide 127

Slide 127 text

The experience ● Other tools ○ systrace: Tool to collect and inspect timing information across all processes running on your device at the system level. ○ dumpsys: Tool to View the Java heap and memory allocations with Memory Profiler 128 @nisrulz

Slide 128

Slide 128 text

The experience ● Other tools ○ bundletool: To recreate, inspect, and verify Google Play’s server-side build of your app’s APKs. ○ perfetto: collect performance information from your Android devices via the Android Debug Bridge (ADB) 129 @nisrulz

Slide 129

Slide 129 text

The experience ● Other tools 130 @nisrulz

Slide 130

Slide 130 text

The experience ● Improving on-demand dependency inclusion 131 @nisrulz

Slide 131

Slide 131 text

The experience … and a lot of cool new things the Android Tools team builds 132 @nisrulz

Slide 132

Slide 132 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-4242e51 ce946 Disable Plugins: https://www.reddit.com/r/androiddev/comments/7sxhig/android_studio_slower_wh en_using_kotlin/dt88pgn/ Battery Historian: https://developer.android.com/studio/profile/battery-historian 133 @nisrulz

Slide 133

Slide 133 text

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

Slide 134

Slide 134 text

135 twitter.com/nisrulz github.com/nisrulz www.nisrulz.com

Slide 135

Slide 135 text

136 twitter.com/nisrulz github.com/nisrulz www.nisrulz.com