My Authors
Read all threads
On #JetpackCompose Alpha day, I want to share a story about Architecture in Compose

When we open sourced Compose at I/O 2019, one of the most common questions from many Android developers was “What does this mean for the architecture of our apps?”
Compose doesn’t change the architecture of your app. The guide to app architecture remains our opinionated guidance for a common architecture for Android apps.

At the same time, there’s been a lot of discussion inside and outside of Google about architecture in Compose apps.
Today, in most Android architectures, the smallest UI component in the architecture is an Activity or Fragment.

This is a natural result of two things:

1) Android speaks Activities (or Fragments)
2) Managing custom views is harder than managing Fragments or Activities
Compose flips this on its head. In Compose the smallest UI component in the architecture can be as small as a single Text or Button.

Everything from an AppNavigator down to a Button is a composable. So the architecture of your UI can fit the architecture of your app.
We quickly realized that composables would need a way to consume state from a ViewModel. To accomplish this we added Compose APIs for reading UI state in compose

LiveData 👉 developer.android.com/reference/kotl…
Flow 👉 developer.android.com/reference/kotl…
RxJava2 👉 developer.android.com/reference/kotl…
One way to use compose is as a replacement for the UI toolkit. Each screen in your app gets an Activity or Fragment and simply uses Compose to render the content.

The architecture for a screen following this pattern doesn't change – use a ViewModel in the Activity or Fragment.
You can also use compose to manage navigation between screens, like we do in the JetNews sample (github.com/android/compos…)

As we explored this, we realized we'd need a way to use ViewModels in Compose. So, we introduced a new API

viewModel 👉 developer.android.com/reference/kotl…
From the beginning, Compose has been designed for unidirectional data flow. That's a design where state flows down and events flow up.

This applies both to big architectures like what you build Android Architecture Components, as well as a single composable.
So now let's talk about architecture inside of Compose.

As you add state to a composable by using ViewModel, you couple that composable with the ViewModel. It becomes stateful.

Stateful composables are harder to reuse, harder to test, and tend to be more complicated.
We can use unidirectional data flow to separate the stateful composable from a stateless composable that just draws the screen. We applied this pattern in JetNews when adding ViewModels

stateful 👉 github.com/android/compos…

stateless 👉 github.com/android/compos…
Using this pattern to extract state from our UI code avoids coupling your UI deeply with your state management.

And, stateless composables are easier to reuse, test, and tend to be simpler.
And now for the story.

To showcase ViewModels and LiveData used in a unidirectional data flow in Compose, we aimed to refactor JetNews to use ViewModel with the alpha launch.

Here's the commit that refactors JetNews to use ViewModel

github.com/android/compos…
When reviewing that, @ppvi noticed that the alpha viewModel API can't be used in our multi-screen Compose app.

github.com/android/compos…

Instead of creating a new ViewModel when entering a screen, it re-used the old one. The details screen would show the wrong article. Uh oh.
We quickly threw together some code to scope a ViewModel to a composable. This fixed the article screen – now it would load the correct article every time it entered.

github.com/android/compos…

It also destroyed the ViewModel on rotation – so we decided to ❌ ship.
So, we backed out ViewModels in the JetNews sample until the Compose APIs can support this use case. Party time, how often do you get to replace an apps architecture twice in one PR 🎉.

Here's ArticleScreen after replacing ViewModel with a new arch.
github.com/android/compos…
And that's it, by following unidirectional data flow in the compose portions of JetNews all we had to change was the stateful composable.

This commit was a complete refactor of the app's architecture and the total change was one composable per screen.

github.com/android/compos…
Compose works with your apps architecture – and it also creates new opportunities to architect your UI code to improve reusability, testing, and avoid complexity.

To learn more check the codelab Using State in Jetpack Compose.

👉 developer.android.com/codelabs/jetpa…
Missing some Tweet in this thread? You can try to force a refresh.

Keep Current with Sean McQuillan

Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!