Upgrade to PRO for Only $50/Yearβ€”Limited-Time Offer! πŸ”₯

Android Studio Poet

Avatar for Boris Farber Boris Farber
May 04, 2018
680

Android StudioΒ Poet

Improve your Android build with Android Studio Poet https://github.com/android/android-studio-poet

Avatar for Boris Farber

Boris Farber

May 04, 2018
Tweet

Transcript

  1. About me β€’ Android/Java/Kotlin β€’ Partner Engineer at Google β€’

    Focusing on Android app optimizations (ClassyShark, AS Poet)
  2. Some metrics we have seen β€’ From 5% to 50%

    build improvement time β€’ Disclaimer β‡’ Heavily depends on β—¦ Project β—¦ Team skills β—¦ Etc… β€’ Take these number with a huge grain of salt
  3. Why β€’ You work relentlessly on your awesome Android app.

    You add new features, libraries and frameworks. β€’ Some more code here, some more resources there, it all ends up impacting the build time.
  4. Why β€’ But it doesn’t have to be that way!

    β€’ As you refactor your classes and methods, why not to treat your Android project as a refactor-able unit
  5. Many variables that affect our build speed β€’ Annotations β€’

    Resources β€’ Java Modules β€’ Android modules β€’ Number of classes β€’ Number of methods β€’ Dependencies β€’ Topology β€’ …
  6. AS Poet β€’ What if we will generate many synthesized

    Android projects with a configurable number of metrics that mimics your project β€’ Then we analyze the build times and understand where are the places to refactor
  7. AS Poet β€’ A desktop based utility for Android developers

    β€’ Generates synthesized Android projects with a configurable number of metrics
  8. How β€’ Let's take a simple JSON file (less than

    20 lines), that mimics the Android projects with gradle plugin syntax β€’ Has number of other parameters such as class/method count ... β€’ AS Poet will read the script and generate a buildable Android Studio project
  9. Sample Script - definitions { "projectName": "genny", "root": "./modules/", "gradleVersion":

    "4.3.1", "androidGradlePluginVersion": "3.0.1", "kotlinVersion": "1.1.60", "numModules": "5",
  10. Sample Script - source data "allMethods": "4000", "javaPackageCount": "20", "javaClassCount":

    "8", "javaMethodCount": "2000", "kotlinPackageCount": "20", "kotlinClassCount": "8", "androidModules": "2",
  11. Sample Script - dependencies & build types "numActivitiesPerAndroidModule": "8", "dependencies":

    [ {"from": 3, "to": 2}, {"from": 4, "to": 2}, {"from": 4, "to": 3} ], }
  12. Features β€’ GUI and CLI β€’ Share resources between Android

    modules (layouts ...) β€’ Call Java/Koltin code between different modules β€’ Build flavours β€’ Topologies β€’ Full format for fain gained control over modules β€’ ...
  13. Swing β€’ Zero Kotlin documentation β€’ All documentation (really good)

    is 20 years old β€’ Ended up doing skeleton development in Java and convert to Kotlin
  14. AS Poet β€’ A desktop based utility for Android developers

    β€’ IO bound app (generates folders with 100K with interconnected dependencies)
  15. Optimizations β€’ Measure, measure and measure β€’ It is better

    to solve the right problem the wrong way than the wrong problem the right way β€’ Our architecture - coroutunes for module creation with fork/join for individual classes write
  16. Projects val timeModels = measureTimeMillis { ModuleBlueprintFactory.initCache() runBlocking { val

    deferredModules = projectConfig.pureModuleConfigs.map { async { ModuleBlueprintFactory.create(it, projectRoot) } } val deferredAndroid = projectConfig.androidModuleConfigs.map { async { ModuleBlueprintFactory.createAndroidModule(projectRoot, it, projectConfig.moduleConfigs) } } temporaryModuleBlueprints = deferredModules.map { it.await() } temporaryAndroidBlueprints = deferredAndroid.map { it.await() } } }
  17. Fork/Join var randomCount: Long = 0 projectBlueprint.androidModuleBlueprints.forEach{ blueprint -> val

    random = Random(randomCount++) val job = launch { androidModuleGenerator.generate(blueprint, random) println("Done writing Android module " + blueprint.name) } allJobs.add(job) } for (job in allJobs) { job.join() }
  18. Cache immutable β€’ Blueprints for methods are immutable β€’ A

    lot of small objects β€’ Caching into deferred maps (inside coroutine)
  19. IO Optimizations 101 β€’ Download only necessary data (gradle full

    versus gradle bin) β€’ Close to 33 MBs saved
  20. Dependency Injection β€’ Injector class β€’ All the objects created

    there β€’ Dependencies are passed as parameters β€’ Maintenance β€’ Testability
  21. Build - FatJar/Gradle β€’ FatJar is a gradle task that

    creates a self contained Jar file with all dependencies