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

7+1 tips about [Android] App Modularization | [Android] Architecture Night

7+1 tips about [Android] App Modularization | [Android] Architecture Night

Nowadays, App modularization is a technique largely adopted that gives lots of advantages. But how to approach it?
This talk will not focus on the pro and cons of modularization but instead on the approach and the process to achieve it. In particular, I want to share the approach that I followed to modularize an existing application and a new one. I want also to share the failures and all the struggles that came in my head while approaching the process.

9da5d5cc4b6a9f28058152e28364b02a?s=128

Marco Gomiero

February 04, 2020
Tweet

Transcript

  1. 7+1 tips about [Android] App Modularization [Android] Architecture Night -

    @marcoGomier
  2. ! What this talk is not about • 101 about

    modularization • Pro and cons [Android] Architecture Night - @marcoGomier
  3. ! What this talk is about • 101 about modularization

    • Pro and cons • Approach and process • Failure and struggles [Android] Architecture Night - @marcoGomier
  4. Marco Gomiero ! Mobile Engineer @ Uniwhere "# $ Co-Lead

    @ GDG Venezia ! Stalking info • Twitter: @marcoGomier • Github: prof18 • Website: marcogomiero.com [Android] Architecture Night - @marcoGomier
  5. Uniwhere Uniwhere is an app that makes college less stressful

    by making university services smarter and more connected. • ! Started in 2015 as MVP • " Lots of iterations • # Time for [more] solid architecture [Android] Architecture Night - @marcoGomier
  6. None
  7. Modularization in few words [Android] Architecture Night - @marcoGomier

  8. Modularization in few words emojis [Android] Architecture Night - @marcoGomier

  9. Modularization in few words emojis • ! Simple development •

    "# Split responsibilities • $ Reusable modules Source: https://speakerdeck.com/beraldofilippo/the-clean-cut?slide=10
  10. Modularization in few words emojis • ! Dynamic features modules

    • " Faster Builds • # Simple test automation Source: https://speakerdeck.com/beraldofilippo/the-clean-cut?slide=10
  11. None
  12. 1 Read and study how to do [Android] Architecture Night

    - @marcoGomier
  13. Doing some research is always a good start [Android] Architecture

    Night - @marcoGomier
  14. Jeroen Mols's series about modularization 1. Modularization - Why you

    should care 2. Modularization - A successful architecture 3. Modularization - Real-life example 4. Modularization - How to approach 5. Modularization - Lessons learned https://jeroenmols.com/blog/
  15. Talk @ Google I/O '19 youtube.com/watch?v=PZBg5DIzNww

  16. Plaid github.com/android/plaid

  17. Article about Plaid https://medium.com/androiddevelopers/a-patchwork-plaid-monolith-to-modularized-app-60235d9f212e

  18. [BONUS] Google I/O Schedule App [https://github.com/google/iosched/tree/master)

  19. [BONUS] Android Dev Summit Schedule App [https://github.com/google/iosched/tree/adssched2019)

  20. 2 Sketch your features [Android] Architecture Night - @marcoGomier

  21. Sketching "un-confuse" your ideas [Android] Architecture Night - @marcoGomier

  22. Monolithic Application └── app └── src └── main └── java

    └── com.prof18.myapplication ├── DashboardFragment.kt ├── HomeFragment.kt ├── MainActivity.kt ├── NotificationsFragment.kt ├── ProfileActivity.kt └── ProfileSettingsActivity.kt [Android] Architecture Night - @marcoGomier
  23. None
  24. How to decide what is a feature? [Android] Architecture Night

    - @marcoGomier
  25. None
  26. None
  27. None
  28. Think a feature as a flow of screens [in the

    same context] [Android] Architecture Night - @marcoGomier
  29. 3 Decide your architecture [Android] Architecture Night - @marcoGomier

  30. There is not a "right way" [Android] Architecture Night -

    @marcoGomier
  31. Modularized App Architecture [Android] Architecture Night - @marcoGomier

  32. Library Modules • Android or Pure Kotlin library • Never

    depend on feature or app • A library can depend on another [Android] Architecture Night - @marcoGomier
  33. Feature Modules • Android library • Never depend on other

    features or app • Depends on one or more libraries [Android] Architecture Night - @marcoGomier
  34. App Module • Android application • Link all the modules

    together • Depends on other features and library [Android] Architecture Night - @marcoGomier
  35. Monolithic Application └── app └── src └── main └── java

    └── com.prof18.myapplication ├── DashboardFragment.kt ├── HomeFragment.kt ├── MainActivity.kt ├── NotificationsFragment.kt ├── ProfileActivity.kt └── ProfileSettingsActivity.kt [Android] Architecture Night - @marcoGomier
  36. Modularized App [1] ├── app │ └── src │ └──

    main │ └── java │ └── com.prof18.myapplication │ └── MainActivity.kt │ [Android] Architecture Night - @marcoGomier
  37. Modularized App [2] └── features ├── home │ └── src

    │ └── main │ └── java │ └── com.prof18.myapplication.features.home │ ├── DashboardFragment.kt │ ├── HomeActivity.kt │ ├── HomeFragment.kt │ └── NotificationsFragment.kt └── profile └── src └── main └── java └── com.prof18.myapplication.features.profile ├── ProfileActivity.kt └── ProfileSettingsActivity.kt [Android] Architecture Night - @marcoGomier
  38. How about navigation? [Android] Architecture Night - @marcoGomier

  39. How about navigation? • Within a feature -> "Classic way",

    e.g. explicit intent, navigation component • Between features -> Implicit intent [Android] Architecture Night - @marcoGomier
  40. Between features navigation Declare the implicit intent in the Manifest

    <activity android:name="com.prof18.filmatic.features.home.ui.HomeActivity" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="com.prof18.filmatic.features.home" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> [Android] Architecture Night - @marcoGomier
  41. Between features navigation Create an object to help you with

    the boilerplate object Actions { fun openHomeIntent(context: Context): Intent = internalIntent(context, "com.prof18.filmatic.features.home") private fun internalIntent(context: Context, action: String) = Intent(action).setPackage(context.packageName) } [Android] Architecture Night - @marcoGomier
  42. How to modularize an existent project? [Android] Architecture Night -

    @marcoGomier
  43. Pull Code Up • Treat the old code "as a

    library" and then create new modules • A gentle process [Android] Architecture Night - @marcoGomier
  44. Pull Code Down • Hold the app together and then

    extract new modules • A more aggressive process [Android] Architecture Night - @marcoGomier
  45. None
  46. Pull Code Up 1. Create new module core 2. All

    existing code into core 3. New app module that decides what to open 4. Extract a new feature from core 5. … [Android] Architecture Night - @marcoGomier
  47. None
  48. [Android] Architecture Night - @marcoGomier

  49. None
  50. Change of strategy: Pull Code Down 1. Maintain all the

    code in the existent app module 2. Move [some] common code to the core module 3. Start creating new features and libraries [Android] Architecture Night - @marcoGomier
  51. 4 Fail as fast as you can [Android] Architecture Night

    - @marcoGomier
  52. Fail as fast as you can • It's ok to

    fail during this process • Keep pushing • Allocate a big initial push to get things started [Android] Architecture Night - @marcoGomier
  53. After failure things get better — me [Android] Architecture Night

    - @marcoGomier
  54. After failure things get better worse — also me [Android]

    Architecture Night - @marcoGomier
  55. String resources • Each module has its strings • Common

    strings on core module • ! for separation of concerns • " to maintain with a "translation platform" [Android] Architecture Night - @marcoGomier
  56. String resources • Each module has its strings • Common

    strings on core module • All strings on core module [Android] Architecture Night - @marcoGomier
  57. 5 Use Dependency Injection. [Android] Architecture Night - @marcoGomier

  58. Let's introduce Dagger while modularizing — me [Android] Architecture Night

    - @marcoGomier
  59. None
  60. Dagger in a multi-module project https://proandroiddev.com/using-dagger-in-a-multi-module-project-1e6af8f06ffc

  61. New to Dagger? https://developer.android.com/training/dependency-injection/dagger-android

  62. How to approach a no Dagger project? • Start gently

    with some [common] dependencies • Continue with more dependencies [Android] Architecture Night - @marcoGomier
  63. 6 Modules configurations. [Android] Architecture Night - @marcoGomier

  64. Modules configuration We need a smart way to handle dependencies

    and configurations across all modules [Android] Architecture Night - @marcoGomier
  65. SDK Configuration subprojects { afterEvaluate { project -> if (project.hasProperty('android'))

    { android { buildToolsVersion Config.buildTools compileSdkVersion Config.compileSdk defaultConfig { minSdkVersion Config.minSdk targetSdkVersion Config.targetSdk testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility Config.javaVersion targetCompatibility Config.javaVersion } } } } } [Android] Architecture Night - @marcoGomier
  66. SDK Configuration object Config { val minSdk = 21 val

    compileSdk = 29 val targetSdk = 29 val javaVersion = JavaVersion.VERSION_1_8 val buildTools = "29.0.0" } [Android] Architecture Night - @marcoGomier
  67. Dependency Management object Versions { val appcompat = "1.0.2" val

    design = "1.0.0" val cardview = "1.0.0" ... } object Deps { val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}" val design = "com.google.android.material:material:${Versions.design}" val cardview = "androidx.cardview:cardview:${Versions.cardview}" ... } [Android] Architecture Night - @marcoGomier
  68. Dependency Management dependencies { implementation Deps.appcompat implementation Deps.retrofit implementation Deps.gson

    ... } [Android] Architecture Night - @marcoGomier
  69. Common dependencies: dependencies { implementation Deps.appcompat implementation Deps.constraintLayout implementation Deps.design

    implementation Deps.vectorDrawable implementation Deps.timber } apply from: '../../shared_dependencies.gradle' [Android] Architecture Night - @marcoGomier
  70. Dependencies Update https://github.com/ben-manes/gradle-versions-plugin

  71. Dependencies Update ./gradlew dependencyUpdates ------------------------------------------------------------ : Project Dependency Updates (report

    to plain text file) ------------------------------------------------------------ The following dependencies are using the latest milestone version: - androidx.cardview:cardview:1.0.0 - androidx.constraintlayout:constraintlayout:2.0.0-beta3 - androidx.emoji:emoji-bundled:1.0.0 .... The following dependencies have later milestone versions: - androidx.appcompat:appcompat [1.1.0 -> 1.2.0-alpha01] https://developer.android.com/jetpack/androidx - androidx.browser:browser [1.0.0 -> 1.2.0-rc01] https://developer.android.com/jetpack/androidx - androidx.core:core-ktx [1.0.1 -> 1.2.0-rc01] [Android] Architecture Night - @marcoGomier
  72. 7 Decide your approach. [Android] Architecture Night - @marcoGomier

  73. What approach to follow? A big sprint? Small chunks of

    work? [Android] Architecture Night - @marcoGomier
  74. My approach • Start with preliminaries • move common code/resources

    to a [or many] core module[s] • Setup the navigation between features • … • Start by modularizing a single feature [Android] Architecture Night - @marcoGomier
  75. My approach • Ship that feature [after testing, QA, etc.

    ] • Start modularizing more features [Android] Architecture Night - @marcoGomier
  76. 8 Create a pet project to try stuff [Android] Architecture

    Night - @marcoGomier
  77. Architecture and modularization require an initial research [Android] Architecture Night

    - @marcoGomier
  78. Conclusions [Android] Architecture Night - @marcoGomier

  79. Conclusions • Plan a big initial push to get things

    started • It's a long [and difficult] journey but it totally worth it • Don't be afraid to fail [Android] Architecture Night - @marcoGomier
  80. None
  81. into modularization! [Android] Architecture Night - @marcoGomier

  82. None
  83. Thanks Q&A [Android] Architecture Night - @marcoGomier

  84. Thanks Q&A • @marcoGomier • github.com/prof18 • marcogomiero.com [Android] Architecture

    Night - @marcoGomier