Jetpack Compose Introduction

Oguz Şahin
Huawei Developers
Published in
11 min readOct 25, 2021

Before begin, I would like to remember that you can read turkish this article from this link.

One of the basic building blocks of an Android application is undoubtedly the design part. In fact, providing a good interface to users not only increases the user experience, but also plays a vital role in to be preferred your product.
Recently on the Android side, Jetpack Compose which has been very popular since the release version was released, it brings a new approach and a breath of fresh air to the existing design coding of developers in the Android application ecosystem.

In this article, I will talk about Jetpack Compose, which some developers are excitedly waiting for and some are anxiously waiting for. The content of the article will progress in a way that I think will help you to say hello to the world of Jetpack Compose firmly and explore the world of Compose. Enjoyable reading now :)

Why did the Android Toolkit Team need tool like Jetpack Compose?

First of all, every new technology must somehow supersede the old one and at the same time find solutions to some of the problems in the old approach. Understanding this situation is perhaps one of the most important steps in learning new technology, I can say for myself. Therefore, before we start rowing in the world of Jetpack Compose, let’s take a look at the problems that the view based design system (the approach of creating UI with xml) has caused to us android developers while designing the UI.

At the same time, let’s understand why the android toolkit team needed a tool like Jetpack Compose. In addition, you can have a first-hand in-depth look at the video in the link by watching the presentation of the android toolkit team.

Code Count of View.java Class

1-) At this point, if we look at one of the first problems, as you can see in the attachment above, the View.java class approaches a terrible figure of 30,000 rows. As we all know, the primary inherited class of every view is the View.java class. The Android toolkit team states that the number of codes reached by this class has become unmanageable, and they want to seek a solution to this as the first problem.

View Inheritance Template

2-) They also state that there is a strange inheritance structure as another problem. As seen in attachment above, we already know that the view based design system is built on an abstraction. Starting from here, if we proceed by considering the example that the Button class inherits from the TextView class, there are cases where the Button text takes on features such as selectable and editable with this abstraction. It would not be very correct behavior for the button to carry these properties. They state that they considered the situation created by the strange inheritance structure here during the development process of Jetpack Compose.

3-) When coding a page with the view based design approach, we usually code an xml layout, collect various common behaviors for views around styles.xml, and when coding structures such as custom views, we write our attributes in the attrs.xml class and finally we set our ui logic in an activity and or fragment (.kt or .java) file. This approach inevitably causes us to write many lines of code. We also use two different languages ​​while doing this coding (java|kotlin & xml). This situation has become one of the problems that the android toolkit team wants to change and improve.

Spinner Class

4-) Suppose that the page we are going to code the design of contains a selection operation. The view we usually use for this is Spinner. F
However, it is obvious that the naming used for this view class (also on other platforms) is Dropdown or ComboBox. Here, Romain Guy states that the naming we use now is an absurd and old naming. He also talks about why it was called spinner before in the presentation in the link I shared. If you want, you can learn about it by watching.

5-) In another case, the Source Of Truth event arising from the distress caused by the imperative ui (we will talk about this in detail later) approach. In the Imperative UI approach; We inflate a layout, then we access the components in it with various methods (findViewById, viewbindig, databindig .. etc.) and by changing the internal states of the accessed views, we provide the state that appears on the screen. If we give an example of state change events that are meant here; Examples can be given such as changing visibility (like gone, visible), setting text to TextView ..etc.

If we go from a checkbox example, when the user checks, the internal state of the view changes and is drawn on the screen, we usually listen for this change with the checkChangedListener and we change a variable we hold accordingly or trigger the work we will do accordingly (for example, making a request in the backend).At this point, what we want to ensure is that the state that the checkbox holds and the state we hold are synchronized. However, the triggering event of the listener can be an action that we will do not only by the user, but also by our code. This can put us in a situation of writing extra and unnecessary code in some cases, since it does not currently go from a single source.

In general, we understood the problems presented by the view based design system we currently use, and we saw what kind of situations the Android Toolkit team took into account when making this change.

Let’s get to know Jetpack Compose

If we make a brief definition; Jetpack Compose is a modern toolkit that allows us to build native android UIs. Jetpack Compose is written entirely with Kotlin and offers us faster, simpler development in a single language, with fewer lines of code. It also comes with support with android studio and other jetpack items. Thus, our development speed is greatly increased. Jetpack Compose offers a declarative ui approach. For now, you can think of this approach as a UI drawn according to data(We will enter the details later). This presents us the beauty of developing from a single source. You can check out the benefits of Jetpack Compose and the opinions of well-known teams (Twitter, Square, Cuvva, Monzo) who have made this transition from this link.

Adding a new tool to a project also affect the apk size and build times of the project. It is useful to evaluate and examine the changes here with Jetpack compose.

Jetpack Compose Apk Size Comparison

On the left side of the picture above, we see the graphic showing the change in apk size after the Tivi application was completely refactored from view based design with jetpack compose. After this transition, the apk size decreased by 49% (from 4.49 mb to 2.39 mb with compose), 17% in the number of methods, and 76% in the number of codes written in XML. On the right, we see the graphic of the Sunflower application, where view based design and jetpack compose are used together. When used together, it increased from 2407 KB to 2982 KB, an increase of 575KB.

Jetpack Compose Build Time Comparison

If we look at the changes in the build times, the build time of the Tivi application was 108.71 seconds before it was refactored. After refactoring, it dropped to 76.96 seconds, a 29% reduction. The situation that most affected this decrease was the removal of Data binding and Epoxy libraries from the project. The reason why these two libraries have such an impact is that they use the kapt annotation processor(They increase the build time as they generate code during build). On the other hand, Sunflower increased 7.6% from 11.57 seconds to 12.45 seconds.

We see that Jetpack Compose also provides us with ergonomics in terms of build time and apk size. (You can also review it from the link.)

In order to better understand and develop Jetpack Compose, it is useful to look at the declarative and imperative UI approaches. On the one hand, it allows us to better understand and grasp the structure of Jetpack Compose, on the other hand, it will be good to look at the comparison of the old and new approaches, to understand and assimilate the new technology.

Imperative Ui

Imperative UI

The Imperative UI approach is the view based approach we currently use while developing android. To summarize briefly what we do in this approach;
first, we create our design by putting various views in an xml layout that we have separated. Then by rendering the layout we created (inflate operation), we enable the user to see it on the screen and interact with the views in it. These views contain certain states within themselves, and we change these internal states according to the user’s interaction to ensure the existing application behavior. In this approach, we proceed with an approach based on how it will appear rather than what appears on the screen.

Declarative Ui

Declarative UI

Declarative UI approach is the approach used in the technologies used in both mobile and web development in the software world. Moreover, the team that developed Jetpack Compose states that they are also inspired by these technologies. Examples include Flutter, React Native, Litho, Vue Js. In this approach, we proceed with the logic of what will appear, not how it will appear this time. We can think about what we will show on the screen according to a certain data. As seen in the picture, there is an interaction by the user and at the end of this interaction, we perform the UI drawing process to be displayed according to the data provided. I would also like to add that this operation is constantly occurring according to the state event. In other words, you are drawing that component on the screen every time.

A good grasp of this approach was one of the most important parts of starting to develop Jetpack Compose for myself. Therefore, I would like to give an example for better understanding. Suppose that we will receive a text input from the user on the screen and display the entered text under the button each time a character is entered. At this point, we can say that the redraw process will take place for each character that the user enters while entering the text. The operating logic is as follows; each time you enter a character, you will have the components redrawn with an observable structure (recomposition event), and with each entered character, the component (Edittext can be considered) will appear on the screen with the last text and the text will be displayed on the screen with its new value, and this flow will continue in this way. State logic in components becomes more stateless with compose. While developing, we will focus on making it as stateless as possible. I will talk about the reasons and advantages of this later.

After learning both of these approaches, let’s reinforce what we have learned with an example and compare the differences between the two approaches.

For example, let’s show an icon based on unread mail status. If there is no unread mail, let’s show an empty envelope. If we have unread mails, let’s have paper in this envelope and at the same time, if the number of unread mails is less than 99, let’s show a badge as 99+ if the number of unread mails is higher. If we have unread mails, let there be paper in this envelope and at the same time, if the number of unread mails is less than 99, the number of unread mails, if it is more; Let’s show a badge as 99+. Also, if it is more than 99, let’s add a fire icon to show our icon.

Coding With Imperative Approach

If we were coding it with the imperative approach, we would be coding considering the state of changing a lot, as seen in the picture above. In case of Update, the state change would cause us to write some more lines of code.

Coding With Declarative Approach

On the other hand, when we code the same example using Jetpack Compose with a declarative UI approach, we can develop much simpler and less lines of code. In this example, as I mentioned above, the UI is drawn dynamically depending on the count data. At the same time, the BadgeEnvolpe composable function will perform the process of drawing again according to the data in each update operation.

Conclusion

In this article, we’ve taken an in-depth look at getting a solid footing into the world of Jetpack Compose. On the one hand, we got to know the jetpack compose toolkit and learned the development processes and what solutions it offers, on the other hand, we learned its logic and operation and got a good grasp of it before development. This post will be the first in this series and in other parts we will start developing Jetpack Compose and try to learn in depth what the concepts used in development are. At the end of the article, I would like to share with you the resources that I used and helped me in the learning phase. Bye stay with the code :)

Footnote: Feel free to share what you see missing or wrong about this article.

--

--