Frequently Asked Questions
Find answers to frequently asked questions about Jetpack Compose!

Jetpack Compose announced its 1.0 release in July 2021. The API surface is fairly stable and Compose is ready to be used in production. If you'd like to learn more about Jetpack Compose, I maintain this repo that will help you get started!

Compose is ready to be used in production and many apps are already working on migrating their apps in production to embrace Compose. Here are some testimonials from companies that have started using Jetpack Compose.

Compose didn't start with the goal replacing fragments per se but it’s a fantastic side effect. In most use cases, you shouldn’t need fragments at all if you are starting a pure compose screen/app. Moreover, since there are millions of apps that still use Fragments, there will most likely be ways to use it with that, although definitely not a requirement.

Compose was built to solve some pain points that the Android developers had been facing since many years. Let's look at what some of those were:

UI is tied to the Operating System
The first reason is that the current UI toolkit is tied to the Android Operating System. What this means is that if we the Android team made some new improvements in the View system or as an example the View.java file, we will have to wait for an Android API release to get these improvements. It's not a simple library that I can just bump up to get these latest improvements & changes. Unbundling the view system from the OS would make it easier to quickly fix bugs and bring improvements in a backward compatible way.

State Management is tricky
The way we managed UI state has always been this complicated dance that we have to do as views store own their own state. And we need to make sure that the state that we store in our view models and presenters is in sync with the state inside of the views. For example, if my business logic requires me to hide a view, that logic is stored in some view model or presenter and then as a reaction to that requirement, I need to get hold of the view I need to hide and explicitly change it's visibility by calling the setVisibility method on the view, which in turn changes the internal state of the view. Now this is really error prone and majority of the bugs in our apps stem from state management. So there has to be a better way.

Lots of Context Switching
Let's talk about the average workflow of an Android developer. We typically create views in xml, then create our screens which have lifecycles in them using Kotlin/Java. We then reference the views that we originally created in xml using id's/tags and then update its state. When we need to reference styles & dimensions, we again store them in xml. This constant context switching definitely has some impact or our productivity and we've come to accept this unfortunately. Now some folks might say that isn't it good that all the UI is in xml files and all business logic in Kotlin files. Decoupling is supposed to be good after all. Well, it's true that decoupling is a good engineering practice but this is not really decoupling because you are still referencing these xml files in your Kotlin code and making modification to it. So even though you might think that xml is decoupled and your UI code is decoupled, in reality it's just an illusion.

Simple things still require a lot of code
We are used to writing a lot of code for even doing simple things. We just spoke about the normal workflow where we are making changes across so many files. Even outside of that, we have so many moving pieces that we need to take care of for writing UI code. Want to make a simple list, you create an adapter first, make sure that it extends the right class, override the relevant methods, If your list supports types of views items, then you override an additional method to pass the relevant layout xml file. So there's a lot of boilerplate code that we have to write for even doing simple things. The most effective way to reduce the number of bugs is to reduce the amount of code that we write.

If you haven't already noticed, here is another shameless 🔌- Learn Jetpack Compose By Example

You should also check out the official samples that are a great way to learn more about Compose.

Lastly, consider going through the Jetpack Compose Pathway.

I maintain a tool that helps you find the equivalent API's in Compose. You can use it here

How can I get started with Jetpack Compose?

You can see the setup instructions here to get your machine ready for doing Compose development.

If you apps are using uni-directional data flow, they will stand to benefit as the migration to Compose would be much smoother. I had spoken about a very relevant topic at Droidcon SF 2019. Towards the second half of the talk, I replace my entire UI with Compose with very little effort.

Video | Slides

@Composable is the secret sauce for Jetpack Compose and it is the most fundamental building block. Annotating a function with @Composable allows that function to describe UI in Compose. This annotation is needed because Compose uses a custom kotlin compiler to function. This custom compiler does some post-processing to each @Composable function and changes its definition at compile time

Android Studio lets you preview your composable functions within the IDE itself, instead of needing to download the app to an Android device or emulator. This is a fantastic feature as you can preview all your custom components(read composable functions) from the comforts of the IDE.

The main restriction is, the composable function must not take any parameters. If your composable function requires a parameter, you can simply wrap your component inside another composable function that doesn't take any parameters and call your composable function with the appropriate params. Also, don't forget to annotate it with @Preview & @Composable annotations.

In addition, you can also deploy a composable function directly to your device for quickly testing it as you are developing it. Android Studio even lets you interact with the components right from Android Studio.

You can continue to use View Models and Live Data with Compose if it fits your use case. Here is an example to help you.

For apps that are fully Compose top-to-bottom, you could just consider providing your dependencies directly via function parameters, lambdas/lexical scope, or using Ambients directly when necessary.

One of the best practices for Compose apps is that UI should be defined in terms of pure data and event callbacks and not have many heavy external dependencies in the first place, so it would maybe be concerning that if UI has a very complex dependency graph it probably isn't separated from business and other non-UI logic as cleanly as it should be.

Using dependency injection can potentially be useful in a mixed codebase that is being migrated to compose, but even then it would probably be cleaner to provide dependencies to the UI in a more Compose-idiomatic way at the boundary between legacy code and compose code

One of the advantages of declarative programming is that you can model these changes through control flow. In order to change UI based on the size of the screen or the orientation, you can simply us an if condition to handle these changes. The compose team also recommends that you handle the config changes manually and then show the appropriate Composable component using logic that takes the available screen size into account.

Presently, it doesn't work with WearOS just yet but we are hopeful that it will be supported in the future.

Flutter and Jetpack Compose are independent projects and aren't necessarily trying to compete with each other. Fluter is a framework for building cross platform native apps. Compose is a new way of writing UI code in native Android. Each have their own merits and use. Since Compose came later on, it definitely did benefit from the learnings of the Flutter team. Both of them are declarative frameworks so they do share some similarities in that regard, however the way they are implemented is different.

Even though there is no layout editor in Compose, I promise you that you won't miss it! Just look at this example of using ConstraintLayout in Compose and be the judge yourself.

Yes you can use existing Android Views and custom views in Compose. Here is an example of what the implementation looks like.

Yes, you can use Compose in existing screens. Compose has an extension function that allows you to add a @Composable function to any view group (like FrameLayout, LinearLayout, etc). Here is an example.

Testing Compose screens feels a lot like unit testing due to the super simple syntax that it provides. Check out this simple example.

A lot of widgets that adhere to the material design specification are already available in Compose. Here are some implementations of the Material Design widgets.

Compose Navigation support has been added to the AndroidX Navigation library. You can check it out here.

Want Jetpack Compose related articles, tips & goodies straight in your inbox ?
Sign up to our newsletter for exclusive content and early access 👇
No spam whatsoever and easy to unsubscribe if you don't like it.