Modular Android Apps

Jarosław Michalik

Android Developer @ Sointeractive
Tech Mentor @

Smart City app

Generic app for concerts, conferences, city events...

Offers, partners, localization, events

  • User profile
  • News
  • City events
  • City transport and navigation
  • Notifications
  • Sponsors and partners list
  • Gamification
  • Social media integration

Various dependencies between components

  • Read article about unknown place in the city
  • Navigate to specific place with speciall offer
  • Notify user about new offer from special partner

And much more...

One project - many cities

Multiple deployments

handle it with gradle flavors

productFlavors {
    roma {
        applicationId ""
        resValue("string", "app_name", "roma")
        versionCode 33
        versionName "$googlePlayVersion"
        manifestPlaceholders = [facebookId: "***************"]
    praga {
        applicationId ""
        resValue("string", "app_name", "praga")
        versionCode 20
        versionName "$googlePlayVersion"
        manifestPlaceholders = [facebookId: "***************"]
    budapest {
        applicationId ""
        resValue("string", "app_name", "budapest")
        versionCode 8
        versionName "$googlePlayVersion"
        manifestPlaceholders = [facebookId: "***************"]

Each city has different

  • app ID
  • server urls
  • transport options
  • languages available
  • RSS (newsfeed)
  • colours

published separately to Google Play

It can be done with Gradle flavors


What if one client doesn't want news?

How to handle different deployments with one codebase?

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            if (BuildConfigHelper.isRomaFlavor()) {

Unused code in production!

New task - add city game

Gamification - that's what we do!

Create new app, or add city game to existing one?

Instead - create module


make smart city app

great again


And great too!

Gamification module

        .httpClient(client) //endpoint and interceptors configured
        .database(dbName) //realm file name

Resources (strings, drawables, styles) are overridden in main app

Gamification module has it's own

  • logic
  • build.gradle
  • networking
  • database
  • views

Shared dependencies:

  • standard and support libraries
  • RxJava
  • Retrofit
  • Dagger

Module can be easily integrated into other app

do not enforce architecture

App can work flawless without module

create some layers of abstraction

Each module can become separate app

config should be simple as possible

So what is module?

something, that provides bossiness logic

something, that can be used many times in different projects

Creating module in Android Studio


    include ':app', ':gamification'

app-level build.gradle

    dependencies {
        compile project(':gamification')

Is this your package?

One package per functionality

Almost good...


Not perfect, just a good start

cleaner architecture -> less painful modularization

Manage dependencies the good way

ext {

    def RxJava2Version = '2.0.6'
    def RxAndroid2Version = '2.0.1'
    def Retrofit2Version = '2.3.0'
    def OkHttp3Version = '3.8.0'

    rxJava2Dependencies = [
            rxJava   : "io.reactivex.rxjava2:rxjava:${RxJava2Version}",
            rxAndroid: "io.reactivex.rxjava2:rxandroid:${RxAndroid2Version}"

    retrofit2Dependencies = [
            retrofit             : "com.squareup.retrofit2:retrofit:${Retrofit2Version}",
            retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${Retrofit2Version}",
            okhttp               : "com.squareup.okhttp3:okhttp:${OkHttp3Version}",
            okHttpLogging        : "com.squareup.okhttp3:logging-interceptor:${OkHttp3Version}",
            gsonConverter        : "com.squareup.retrofit2:converter-gson:${Retrofit2Version}"


top-level build.gradle

apply from: 'dependencies.gradle'

module-level build.gradle

compile rxJava2Dependencies.values()

Compile only things you need

testCompile jUnitDependencies.values() //only test builds

compile supportDependencies.values() //compile for all

flavorOneCompile gameDependencies.values() //compile in flavor build
flavorOneCompile newsDependencies.values()

flavorTwoCompile newsDependencies.values()

Gradle tips - use dependency only during compilation

provided codeGenerationTools.values()

Ultimate goal - share modules across projects

Share module between phone app, smartTV or Android Things!

Separate app for module

e.x app displaying news and news only

Separate git repo for module


Prepare mock backend for module

At Sointeractive we use RAML (Rest Api Modelling Language)

Simple mock backend - ready to use with module demo app

Module sharing

git clone from module repo...


Use maven artifactory!

    compile "com.yourcompany.modules:gamification:1.0.2"
    compile "com.yourcompany.modules:news:1.2.4"

Next level modularization



New app for major functionality

But they actually can convince users to download another app

Why you should try modules?

Your app is too large

You provide similar features to different customers

You build app across the teams

You want to go open source someday

Code as a crime scene

Tool to analyse code

You want to try some new technologies, patterns or architecture

Don't create module if...

you are 100% sure that was one-time project

you don't have to maintain app

you have to meet the deadline

Smart City before

One module (app), various "ifs", unused code in production

Average compilation time: 15min

Smart City now

  • news module
  • gamification module
  • tripplanner module
  • Sointeractive beacon library

Compilation time after modularization:


Average apk size (for different cities)





Thank you!

Jarosław Michalik


Why we still use Java 7 in Android?