Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

! What this talk is about • 101 about modularization • Pro and cons • Approach and process • Failure and struggles [Android] Architecture Night - @marcoGomier

Slide 4

Slide 4 text

Marco Gomiero ! Mobile Engineer @ Uniwhere "# $ Co-Lead @ GDG Venezia ! Stalking info • Twitter: @marcoGomier • Github: prof18 • Website: marcogomiero.com [Android] Architecture Night - @marcoGomier

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Modularization in few words emojis • ! Dynamic features modules • " Faster Builds • # Simple test automation Source: https://speakerdeck.com/beraldofilippo/the-clean-cut?slide=10

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

1 Read and study how to do [Android] Architecture Night - @marcoGomier

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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/

Slide 15

Slide 15 text

Talk @ Google I/O '19 youtube.com/watch?v=PZBg5DIzNww

Slide 16

Slide 16 text

Plaid github.com/android/plaid

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

How to decide what is a feature? [Android] Architecture Night - @marcoGomier

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Think a feature as a flow of screens [in the same context] [Android] Architecture Night - @marcoGomier

Slide 29

Slide 29 text

3 Decide your architecture [Android] Architecture Night - @marcoGomier

Slide 30

Slide 30 text

There is not a "right way" [Android] Architecture Night - @marcoGomier

Slide 31

Slide 31 text

Modularized App Architecture [Android] Architecture Night - @marcoGomier

Slide 32

Slide 32 text

Library Modules • Android or Pure Kotlin library • Never depend on feature or app • A library can depend on another [Android] Architecture Night - @marcoGomier

Slide 33

Slide 33 text

Feature Modules • Android library • Never depend on other features or app • Depends on one or more libraries [Android] Architecture Night - @marcoGomier

Slide 34

Slide 34 text

App Module • Android application • Link all the modules together • Depends on other features and library [Android] Architecture Night - @marcoGomier

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

Modularized App [1] ├── app │ └── src │ └── main │ └── java │ └── com.prof18.myapplication │ └── MainActivity.kt │ [Android] Architecture Night - @marcoGomier

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

How about navigation? [Android] Architecture Night - @marcoGomier

Slide 39

Slide 39 text

How about navigation? • Within a feature -> "Classic way", e.g. explicit intent, navigation component • Between features -> Implicit intent [Android] Architecture Night - @marcoGomier

Slide 40

Slide 40 text

Between features navigation Declare the implicit intent in the Manifest [Android] Architecture Night - @marcoGomier

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

How to modularize an existent project? [Android] Architecture Night - @marcoGomier

Slide 43

Slide 43 text

Pull Code Up • Treat the old code "as a library" and then create new modules • A gentle process [Android] Architecture Night - @marcoGomier

Slide 44

Slide 44 text

Pull Code Down • Hold the app together and then extract new modules • A more aggressive process [Android] Architecture Night - @marcoGomier

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

[Android] Architecture Night - @marcoGomier

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

4 Fail as fast as you can [Android] Architecture Night - @marcoGomier

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

After failure things get better — me [Android] Architecture Night - @marcoGomier

Slide 54

Slide 54 text

After failure things get better worse — also me [Android] Architecture Night - @marcoGomier

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

String resources • Each module has its strings • Common strings on core module • All strings on core module [Android] Architecture Night - @marcoGomier

Slide 57

Slide 57 text

5 Use Dependency Injection. [Android] Architecture Night - @marcoGomier

Slide 58

Slide 58 text

Let's introduce Dagger while modularizing — me [Android] Architecture Night - @marcoGomier

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Dagger in a multi-module project https://proandroiddev.com/using-dagger-in-a-multi-module-project-1e6af8f06ffc

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

How to approach a no Dagger project? • Start gently with some [common] dependencies • Continue with more dependencies [Android] Architecture Night - @marcoGomier

Slide 63

Slide 63 text

6 Modules configurations. [Android] Architecture Night - @marcoGomier

Slide 64

Slide 64 text

Modules configuration We need a smart way to handle dependencies and configurations across all modules [Android] Architecture Night - @marcoGomier

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Dependency Management dependencies { implementation Deps.appcompat implementation Deps.retrofit implementation Deps.gson ... } [Android] Architecture Night - @marcoGomier

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

Dependencies Update https://github.com/ben-manes/gradle-versions-plugin

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

7 Decide your approach. [Android] Architecture Night - @marcoGomier

Slide 73

Slide 73 text

What approach to follow? A big sprint? Small chunks of work? [Android] Architecture Night - @marcoGomier

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

My approach • Ship that feature [after testing, QA, etc. ] • Start modularizing more features [Android] Architecture Night - @marcoGomier

Slide 76

Slide 76 text

8 Create a pet project to try stuff [Android] Architecture Night - @marcoGomier

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

Conclusions [Android] Architecture Night - @marcoGomier

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

into modularization! [Android] Architecture Night - @marcoGomier

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

Thanks Q&A [Android] Architecture Night - @marcoGomier

Slide 84

Slide 84 text

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