Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

[Droidcon Greece '19] My love-hate relationship...

[Droidcon Greece '19] My love-hate relationship with Android Studio

Android Studio is the tool of the trade hands down. When it comes to Android (app/library/IoT) development, the first thing that comes to mind is to install Android Studio and get going from there. However, it has not been a smooth road as expected for me. In my own experience, I talk about my love-hate relationship with Android Studio. I try to cover what Android Studio gets right and what it doesn't. The talk focuses on how to be embrace performance when Android Studio is the bottleneck in the workflow (slow build times and reduced productivity), how switching to a terminal and various tools that exist in the ecosystem can give Android developers the much-needed speed boost and in-depth view in their development workflow. By the end of this talk, you would have embraces a workflow that allows for increased productivity and faster development.

Google Slides: https://docs.google.com/presentation/d/1sO_F9sGIEuaxtmRkVRuZZmM2YhmZK7BVmHjzIhOvcmE/edit?usp=sharing

Event: https://web.archive.org/web/20190921200216/https://droidcon.gr/agenda/

Nishant Srivastava

September 25, 2019
Tweet

More Decks by Nishant Srivastava

Other Decks in Technology

Transcript

  1. 2

  2. What happened • Trying to build an Android Project ◦

    Typical project ◦ Multi module 5 @nisrulz
  3. What happened • Trying to build an Android Project ◦

    Native code (NDK) ◦ Common dependencies: Retrofit, Dagger, Rx, Support Libraries, etc 6 @nisrulz
  4. What happened • Laptop: Macbook Air (early 2014) ◦ Core

    i5(1.4 Ghz) ◦ 4GB DDR3 RAM ◦ 128GB SSD ◦ Intel HD Graphics (1.5GB) 7 @nisrulz
  5. What happened My build times: ~37 min Not just the

    first time, but every other build after that too 9 @nisrulz
  6. What happened With a few gradle tweaks in the project.

    12 @nisrulz https://guides.gradle.org/performance/
  7. What happened Build times down to ~28 min With a

    few gradle tweaks in the project. 13 @nisrulz https://guides.gradle.org/performance/
  8. What happened Switched to Terminal builds and VS Code Editor.

    15 @nisrulz + After exhausting all possibilities.
  9. What happened 18 @nisrulz + Build times down to ~3

    minutes( 89% reduction) Final result.
  10. The experience State of reliability: Critical issues 28 @nisrulz ~3

    months https://issuetracker.google.com/issues/133864394
  11. The experience To a point where someone had to build

    this: A nuke script! https://github.com/rock3r/deep-clean 31 @nisrulz
  12. 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
  13. The experience State of tools: Limited 48 @nisrulz Apply Changes

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

    https://developer.android.com/studio/known-issues#appl y-changes-ki-verification-errors
  15. The experience To summarize, Android Studio is • Slow •

    Finicky • Forces its defaults and deviates from its base 51 @nisrulz
  16. The experience To summarize, Android Studio is • New tools

    are limiting ◦ Energy Profiler ◦ Constraint Layout Editor ◦ Resource Manager ◦ Apply Changes ◦ Deployments options 52 @nisrulz
  17. The experience To summarize, Android Studio is • Uses a

    lot of Memory and CPU • Has versioning quality problem (Stable, Beta, Alpha) 53 @nisrulz
  18. Slow, but why? • Gradle Configuration • Indexing changes in

    code • Plugins • Code Insight: Inplace analysis/inspections 55 @nisrulz
  19. Configuring Gradle for speed Use the latest Gradle release. 56

    @nisrulz Incremental compile 1000-module Java project https://gradle.org/whats-new/gradle-5/
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. Reducing Indexing If your codebase has files changing on each

    build, it will trigger indexing. 63 @nisrulz
  27. 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
  28. Plugins: Inspect what you use Android Studio comes with a

    lot of Plugins enabled, which contribute to its sluggishness. 65 @nisrulz
  29. Code Insight Although required, it does make Android Studio slow.

    Solution: Enable Power Save Mode 67 @nisrulz
  30. ADB: Android Debug Bridge • Command Line tool • Shipped

    with Android SDK • Allows interacting with debuggable Android devices • Client-Server program • Available as: adb <param> 69 @nisrulz
  31. ADB: Android Debug Bridge • Install App ◦ adb install

    path_to_apk • Uninstall App ◦ adb uninstall com.package.name 70 @nisrulz
  32. 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
  33. 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
  34. 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
  35. Gradle The same can be done via terminal: ./gradlew assembleDebug

    > is equivalent to Make in Android studio 74 @nisrulz
  36. 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
  37. 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
  38. Detekt https://github.com/arturbosch/detekt // Execute at the root of the project

    java -jar /path_to/detekt-cli.jar --debug 79 @nisrulz
  39. 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
  40. 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
  41. AVD Manager • Command line tool to create and manage

    Android Virtual Devices (AVD) • Located in android_sdk/tools/bin/ 85 @nisrulz
  42. 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
  43. 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
  44. 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
  45. 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
  46. SDK Manager // List all available packages sdkmanager --list //

    Install packages sdkmanager packages // Remove packages sdkmanager --uninstall packages // Update all packages sdkmanager --update 90 @nisrulz
  47. 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
  48. 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
  49. IntelliJ Idea • Android Studio is based on IntelliJ Idea

    ◦ IntelliJ Idea can be used for Android Development • Faster for development 95 @nisrulz
  50. IntelliJ Idea • Consumes less memory/CPU than Android Studio •

    Full plugin support • More frequent updates 96 @nisrulz
  51. IntelliJ Idea • Doesn’t have the Android Studio specific tools

    ◦ Constraint Layout Editor ◦ Profilers ◦ Resource Manager ◦ Apply Changes 97 @nisrulz
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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 <command> is the equivalent of ./adb -s <serial number> <command> # # Examples # ./adbe version ./adbe install demo_app.apk 105 @nisrulz https://github.com/nisrulz/terminal-utils/blob/master/android/adbe.sh
  60. 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
  61. 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
  62. Automation • Use gradle plugin to setup all the automation

    commands Some commands available: • installDevice<Variant> - installs the app on a specific device. • uninstallDevice<Variant> - uninstalls the app from a specific device. • run<Variant> - installs and launches the app on a specific device. and many more. Execute: ./gradlew installDeviceDebug 108 @nisrulz
  63. 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
  64. 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
  65. The experience • APK Analyzer(Command line) // To print the

    file size of the apk in a human readable format //Output: 1.7MB 115 @nisrulz
  66. 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
  67. 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
  68. 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
  69. The experience • Size Analyzer // Tool to understand the

    size of Android application. size-analyzer check-bundle <path-to-aab> size-analyzer check-project <path-to-project-directory> More info: https://github.com/android/size-analyzer 119 @nisrulz
  70. 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
  71. The experience • Simpleperf A versatile command-line CPU profiling tool

    included in the NDK for Mac, Linux, and Windows. 123 @nisrulz
  72. 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
  73. 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 <source-file>:<line-number> from your source code, making debugging easier. 125 @nisrulz
  74. 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
  75. 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
  76. 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
  77. 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
  78. The experience … and a lot of cool new things

    the Android Tools team builds 132 @nisrulz
  79. 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