Jetpack: Compose

Cayce Osborn
Neudesic Innovation
5 min readMay 22, 2023

--

An Introduction to the Framework

In this article, the reader can expect to gain a general understanding of the pros and cons of Compose. So, where to start? At the beginning, of course!

What is Jetpack?

Jetpack, essentially is a suite (or collection of libraries) published in the Android namespace with Kotlin in mind. These libraries were designed to eliminate the need for writing time-consuming boilerplate code. They can also be sorted into a few categories:

  • Architecture
  • UI (User Interface)
  • Foundation
  • Behavior

Examples of Jetpack’s libraries, of which will be discussed in follow-up articles, include:

  • WorkManager (for scheduling needs)
  • Room (for data storage persistence)
  • Navigation (for application navigation flow management)
  • CameraX (for adding camera capabilities)
  • and, of course, the reason for this article, Compose (for building UI)

Compose was created and introduced by Google in 2019 and has been in continuous development since. It’s an annotation-based framework that combines a React programming model with Kotlin. Compose was designed to transition from Android Native’s imperative UI design to a declarative one. If the developer has been exposed to Swift, Flutter, or React, they will feel at home with Compose.

Advantages of Compose

  • Ease of Use!
    To utilize Compose, all one needs to do is add a Compose annotation above a function. It’s that simple.
  • There is no need to learn and struggle with XML!
    Compose allows the developer to add stylization and attributes to components directly within the composable functions. This eliminates many lines of boilerplate code, which lessens the chance for bug creation. Also, if there are no parameters being passed into the function, it allows the developer to view their changes nearly instantaneously using Preview.
  • Preview!
    If any individual has had to deal with Android Studio’s emulators, they know how time consuming it can be to, not only build and run your app to display changes, but also deal with emulator issues. With the addition of the Preview annotation, any composable function containing no parameters can be observed by the developer without having to run their emulator. If a Composable does have parameters, there is a work around; A separate Composable would need to be created with no parameters. Above the Composable annotation, a Preview annotation is added. Lastly, the Composable seeking to be viewed would be placed within the Preview Composable with all required parameters. It’s an additional few lines of code that can significantly improve UI design by cutting back on the reliance on the emulator and its wait times. (See example below)
// An example of a Preview Composable function calling a 
// Composable function with a parameter.

@Preview
@Composable
fun LazyColumnPreview() {
JPCompose(Users)
}
Split design of above Preview
  • Speed and Size!
    Simply put, Compose is fast. Utilizing it also greatly reduces the size of the APK (Android Package Kit) potentially resulting in increased user retention of the application. As a test, the application containing the above image was created twice: Once with Native and a second time with Compose. The image below shows the resulting APK size of both, incredibly small applications.
Three XML files and an Adapter Class separate these sizes
  • Easier Maintainability and Readability!
    With less code being written and less files needed due to the absence of XML, the resulting codebase is easier to read and maintain for the developer.
  • It’s Intuitive!
    Compose attempts to ensure the correct Composable functions are run in the correct order. If a Composable had calls to other Composables, the first assumption would be that there would be a necessity for ordering; However, the framework is able to recognize and draw the higher priority UI elements first.
  • Recomposition!
    Being as Compose is declarative, to change the data in the view, no longer is it necessary to call a setter and notify the UI that there has been a change. All that needs to be done is to merely call the Composable function again containing the new data.
  • Pessimistic? No, Optimistic!
    With the dynamistic nature of Compose’s recomposition, if any parameters change prior to the recomposition efforts of the Composable, it can cancel and restart the recomposition containing the newly changed parameter or data.
  • Lazy Components!
    RecyclerViews are a widely used and oft groaned-at container to implement. LazyColumns or LazyRows take its place, eliminating the need to create an Adapter Class.
// The Composable function that was called in the Preview 
// displayed above. This is the replacement for the
// RecyclerView Adapter class.

@Composable
fun JPCompose(userList: List<User>) {
Surface(
modifier = Modifier
.padding()
.fillMaxHeight()
.fillMaxWidth()
) {
LazyColumn(
modifier = Modifier.fillMaxSize(1f),
contentPadding = PaddingValues(16.dp)
) {
item {
Row(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {}
}
items(userList.size) { user ->
UserCard(userList[user].name, userList[user].imageId)
}
}
}
}

Disadvantages of Compose

No languages or framework is perfect and Compose is no exception. Even though the Jetpack suite is still being continuously developed and some of these issues might be resolved in the future, here are some drawbacks:

  • Learning Curve.
    If the developer is new to declarative languages, there is a significant learning curve to be expected greater than with developers who have.
  • Lack of Resources.
    Being as the suite is still quite young, if StackOverflow or ChatGPT are relied upon to solve the developer’s hyper-specific issues, chances are the solution will not be found in whole. Also, there is a lack of 3rd party libraries, so any clever ideas may not be attainable with Compose alone.
  • Running Frequency.
    While the running frequency of the Composables can be considered an advantage, depending on what it’s used for it can be detrimental. Composables have the ability to recompose one to hundreds of times a second. If the Composable running contains any expensive operations like reading internal storage, this could cause UI jank and greatly impact the application’s performance. The developer would need to be cognizant of ensuring the expensive work that needs doing be on a separate thread outside of the composition and passed in using methods, such as LiveData or mutableStateOf.

Conclusion

Even with the detrimental aspects of Compose, the framework seems highly useful to, not only the developers, but to the product owner. It’s a highly intuitive and relatively easy-to-use framework that saves time. With less time spent on development, a faster running and smaller sized application, and a library that is in continuous development, the choice seems simple: This may very well become the industry standard for Android development in the near future.

--

--

Cayce Osborn
Neudesic Innovation

Coffee driven, NHL loving, Kotlin developing, cat fathering, boardgame enthusiast.