Sign in

Eric Silverberg

The missing lifecycle diagram for reactive Android Apps

How Activities, Repositories and Databases fit together on Android. Photo by Bill Oxford on Unsplash

Every Android developer working with an MVVM architecture faces the choice of how and when to configure views and subscriptions. Do this incorrectly and you will experience seemingly impossible NullPointerExceptions, as we documented earlier in this series.

To avoid these consequences, simplify your code and streamline your architecture, our company has developed its own proposed Activity and Fragment lifecycle that we have dubbed the Clean MVVM Activity Lifecycle:

Learn this now or spend 🤷‍♂️ in Crashlytics later

For a class we didn’t even write, Parcel sure seems to have some problems…Photo by Markus Winkler on Unsplash

In this series, we spoke at length about how Android process death can trigger crashing on apps that do not follow a Clean MVVM Application lifecycle pattern. In order to debug Android process death, you need to first trigger a process death, and then you need to restore your application to see how it behaves.

Step 1: Trigger process death

Method A: Use adb

Put your app into the background by pressing the home button

Kill the app using adb:

adb shell am kill <YOUR APPLICATION ID>

DON’T use the “Stop” button of Android Studio to kill the process. This will not simulate a process death and it…

The red bar is the legacy Activity Lifecycle

Every developer will ask herself these questions when writing a new activity — here are quick answers when doing so using our Clean MVVM Activity Lifecycle:

Where do I initialize my ViewModel?

→ Lazily as a member variable:

private val viewModelFactory: FeatureViewModelFactory by inject()
private val viewModel: FeatureViewModel by viewModels { viewModelFactory }

Where do I set up the views and the click listeners?

onSetupViews(), one of our custom Clean MVVM Lifecycle methods

Where do I set up the state change subscription? (LiveData)

onSetupLiveDataEventSubscriptions(), one of our custom Clean MVVM Lifecycle methods

Where do I set up the events subscription? (RxJava)

onSetupAliveActivityRxJavaEventSubscriptions() for subscriptions that we want to retain even if the app is backgrounded (most of the cases)

onSetupVisibleActivityRxJavaEventSubscriptions() for subscriptions that we want to cancel when the app is backgrounded

Where do I handle deep links?

Initializing your app’s database at startup — easier said than done!

Don’t block the main thead! Photo by amirali mirhashemian on Unsplash

How do you initialize a repository? More precisely, how do you initialize application-scoped classes with database dependencies?

If you’re an iOS developer, the answer to the question about is probably “synchronously on the main thread, in my Application delegate during didFinishLaunchingWithOptions, what’s the big deal?” On iOS, because of the strong guarantees about startup sequencing and fast nominal performance of devices, this answer usually works, even if you are *technically* doing blocking I/O on a UI thread.

If you’re an Android developer, if you provide the same answer, you know that you are committing a Strict Mode Violation, but, given…

Android process death, unexplainable NullPointerExceptions, and the MVVM lifecycle you need right now

There is a ghost in the Android machine! (Photo by Rami on Unsplash)

The Android activity lifecycle is one of the first architectural concepts learned by a new Android developer. Ask any Android dev and they’ll likely all have seen this handy diagram from Google:

Android process death — what every mobile dev ought to know

Who is that mysterious culprit? Photo by Carlos Alberto Gómez Iñiguez on Unsplash

Most Android developers understand that their Activity can be killed at any time when it is in the background. Indeed, this is one of the critical features provided by any operating system.

Most Android developers have also probably used Crashlytics and seen stacks with seemingly “impossible” NullPointerException crashes, right around the start of an Activity or Fragment. Try it — go launch and see how far down you must scroll before you see an exception matching this pattern. I bet it’s not far!

The solution to this class of problem starts first with a firm understanding of Android Process…

Life in the outer layer of Clean MVVM is platform-specific

That’s what I call a View

At the outer layer of our Clean MVVM hierarchy are Views, including Activity and UIViewController, and these are represented by the blue 🔵 parts of our Clean architecture.

We can think of the view as the class that defines what to draw on the screen and how to draw it, but not when or why. The “when” is decided by the view model, and the “why” by the logic. Below is a summary of different types in this layer:

View classes should have…

A summary of architecting and testing apps in Swift + Kotlin

In our series on Clean MVVM, we have shared real-life lessons shipping a major mobile client on multiple platforms for more than a decade. Clean MVVM is an architectural approach for building consistent apps in Swift and Kotlin, to maximize architectural and code design re-use. At its best, Clean MVVM enables you to copy-and-paste Swift into Kotlin, or Kotlin into Swift, and just twiddle the syntax.

Yes, this will be on the test

Below are the key points across all articles in this series, helpfully summarized:


API classes initiate network calls to one remote service, specific to the Repository you are implementing. Though it may be tempting for your API class to itself interact with the network, don’t do it — instead, inject an HTTP client (such as Retrofit on Android) into your API class that itself provides general-purpose network access, including adding necessary authorization parameters and headers.

What you’re going to do to that network response

Each feature area is broken up into a specific interface that defines the necessary GET/POST/PUT/DELETE operations for that feature. API classes are always injected into Repositories. …

What comes after an API response?

This repository could probably use a refactoring, but those domain models sure look tasty. Photo by Marc Noorman on Unsplash

APIs are like the engines of apps — every app has them, and they provide the fuel that makes the app work. But what happens after an API call completes? How is the data managed, munged, and manipulated before it is (ultimately) rendered in a View on iOS or Android?


Perry Street Software has been publishing apps since 2010, and in this series of blog posts, we introduce the Clean MVVM architecture for consistent cross-platform code in Swift and Kotlin.

The center of our abstraction — Repositories and Domain Models — is the…

Eric Silverberg

CEO, Perry Street Software. Developer. 🏳️‍🌈

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store