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.
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 ( https://github.com/android/compose-samples/blob/2107dc42de5ec6c178ca57df605908a2de31011f/JetNews/app/src/main/java/com/example/jetnews/ui/JetnewsApp.kt#L70)

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

viewModel 👉 https://developer.android.com/reference/kotlin/androidx/compose/ui/viewinterop/package-summary#viewmodel
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.
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.
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.

https://github.com/android/compose-samples/blob/f8dc797d8677eb68fe8134c0b274c4bc9ceb13ec/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt#L77

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.
https://github.com/android/compose-samples/blob/19b5e1cc163b1e4b4f2cba850cddf07766eaa019/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt#L73
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.

👉 https://developer.android.com/codelabs/jetpack-compose-state
You can follow @objcode.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: