Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Devoxx Poland '19] My love-hate relationship with Android Studio

[Devoxx Poland '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 embraced a workflow that allows for increased productivity and faster development.

Event Link: https://web.archive.org/web/20190610115625/https://cfp.devoxx.pl/talk/JCI-4114/My_love-hate_relationship_with_Android_Studio
Google Slides: https://docs.google.com/presentation/d/1WFDszY4fSLu-tAJC-rw-gOKFOnRPo4SwRveAtVXgSq0/edit?usp=sharing

Nishant Srivastava

June 24, 2019
Tweet

More Decks by Nishant Srivastava

Other Decks in Technology

Transcript

  1. 1

    View Slide

  2. The disclaimer.
    @nisrulz 2

    View Slide

  3. The story.
    @nisrulz 3

    View Slide

  4. 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

    View Slide

  5. 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

    View Slide

  6. What happened
    6
    @nisrulz

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  10. What I tried
    After exhausting all possibilities
    10
    @nisrulz

    View Slide

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

    View Slide

  12. 12
    @nisrulz
    +

    View Slide

  13. What I tried
    The result
    13
    @nisrulz
    +

    View Slide

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

    View Slide

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

    View Slide

  16. The experience.
    @nisrulz 16

    View Slide

  17. The experience
    State of speed:
    Slow
    17
    @nisrulz

    View Slide

  18. The experience
    State of reliability:
    Finicky
    18
    @nisrulz

    View Slide

  19. The experience
    State of reliability:
    Finicky
    19
    @nisrulz

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  23. The experience
    State of memory consumption:
    23
    @nisrulz

    View Slide

  24. The experience
    State of memory consumption:
    24
    @nisrulz

    View Slide

  25. The experience
    State of CPU consumption:
    25
    @nisrulz

    View Slide

  26. The experience
    State of CPU consumption:
    26
    @nisrulz

    View Slide

  27. The experience
    State of updates/versions:
    27
    @nisrulz

    View Slide

  28. 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

    View Slide

  29. is slow.
    @nisrulz 29

    View Slide

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

    View Slide

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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

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

    View Slide

  39. 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

    View Slide

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

    View Slide

  41. Terminal to the rescue.
    @nisrulz 41

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

  47. Lint
    47
    @nisrulz

    View Slide

  48. 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

    View Slide

  49. 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

    View Slide

  50. Classyshark
    50
    @nisrulz

    View Slide

  51. Classyshark
    51
    @nisrulz

    View Slide

  52. 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

    View Slide

  53. 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

    View Slide

  54. 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

    View Slide

  55. 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

    View Slide

  56. 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

    View Slide

  57. Battery Historian
    57
    @nisrulz

    View Slide

  58. Battery Historian
    58
    @nisrulz

    View Slide

  59. 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

    View Slide

  60. 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

    View Slide

  61. 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

    View Slide

  62. 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

    View Slide

  63. 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

    View Slide

  64. 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

    View Slide

  65. The experience.
    @nisrulz 65

    View Slide

  66. 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

    View Slide

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

    View Slide

  68. 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

    View Slide

  69. 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

    View Slide

  70. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide