A deep dive into the Java/Kotlin code compilation process for an android application.

A deep dive into the Java/Kotlin code compilation process for an android application.

Have you ever been curious about what actually happens when you compile your Java/Kotlin code and run it on an Android device? Do you want to know what happens in the background during this process?


??This tutorial is designed?for:

Who has the basic knowledge of Gradle, how to use it and why we use Gradle. If you are new to Gradle (don’t worry), I recommend this article before reading this. It will be more than enough because I want you after completing these two articles to understand and have a very good knowledge about Gradle and android compilation process.


??The purpose of this tutorial?is:

The purpose of this article is to provide a clear explanation of how an Android app is compiled (compilation process).

As you may already know, Android apps can be created using Java and Kotlin programming languages. So, when it comes to compiling Android apps, the process is based on how Java and Kotlin code are compiled (excluding the Android-specific part). So, let’s get familiar with these two processes (Java and Kotlin Complication).


??(1) Let’s start by compiling the Java code?first:

To make Java code work, we need to go through a few steps. Let’s say we have a file called TestClass.java that we want to run. Here are the steps for compiling that file:

  1. TestClass.java is compiled by javac (Java compiler).
  2. Javac compiles Java source file into Java byte-code file as TestClass.class.
  3. Java byte-code file (TestClass.class) ends up in JVM (Java Virtual Machine).
  4. JVM understands byte-code and converts it into machine code, using JIT (Just-In-Time) compiler.
  5. The machine code is then fed to the memory and executed by computer’s central processing unit.

That’s basically the entire process of running Java code, but I’d also like to explain a few of the terms mentioned.

  • Java byte-code — representation of Java assembly

// Java regular code
public int addTwoNumbers(int a, int b) {
    return a + b;
}

//*********************************************************//

// Java byte-code equivalent
public int addTwoNumbers(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: iadd
       3: ireturn        

  • JVM (Java Virtual Machine) — engine which provides runtime environment for execution of Java code.
  • JIT (Just-In-Time) compiler — this refers to a specific type of compiler that performs the compilation while the program is being executed, meaning it compiles the app when the user opens it. (compiles the app when user opens it).

Having discussed these aspects, we have covered all the important points related to the compilation of Java code.


??(2) Let’s move on to the second compilation of Kotlin?code:

In simple terms, Kotlin is a programming language that is open-source and statically-typed. It is used to create code that can run on the JVM (Java Virtual Machine).

In order for Kotlin to work on the JVM, it needs to be converted into Java byte-code through compilation. If we refer to Kotlin’s frequently asked questions (FAQ), we can confirm that this is precisely what the Kotlin compiler does as shown in figure 1.

No alt text provided for this image
Figure 1: Java and Kotlin compilation processes

By looking at the left the side of image in figure 1, we can see that the compilation processes of Java and Kotlin are very similar.

Note: In desktop App not mobile app cycle java using JVM for more info you can find it here.


??Let’s dive into another important thing which is the Android compilation process

??Please be aware: the main difference between regular Java/Kotlin code compilation and the Android compilation process is that Android doesn’t use the JVM (Java Virtual Machine). If you’re wondering why, you can find the explanation at the end of the article.??

Instead, Android chose to create two special virtual machines specifically for Android:

  1. DVM (Dalvik Virtual Machine).
  2. ART (Android Runtime) was introduced when Android 4.4 (KitKat) came out (released), and before that, Android apps used a different runtime environment called DVM (Dalvik Virtual Machine).

?? Know that later in this article, we will discuss the differences between DVM and ART. ??

Regarding their functionalities, both ART and Dalvik are compatible runtimes that execute Dex byte-code, which is stored in?.dex files.

??? Now, the question arises: where do we get the?.dex file from?

It appears that there is an additional compiler positioned between Java byte-code (.class file) and DVM. This compiler is known as DX (DEX compiler), and its role is to transform Java byte-code into Dalvik byte-code.

So, now we can say that we have all the necessary elements, we can represent the Android compilation process as follows in figure 2.1and Figure 2.2:

No alt text provided for this image
Figure 2.1: Full Android Compilation Process
No alt text provided for this image
Figure 2.2: Full Android Compilation Process

This is called the?Ahead-of-time compilation. The benefit is it runs faster during app launching at the expense of executable file size.

??Lets take an example code of Dalvik byte-code:

It’s quite fascinating to see what Dalvik byte-code looks like. Here’s an example of the “addTwoNumbers” function in its regular code form, its equivalent in Java byte-code, and its corresponding representation in Dalvik byte-code.

// Java regular code
public int addTwoNumbers(int a, int b) {
    return a+ b;

//*********************************************************//

}// Java byte-code equivalent
public int addTwoNumbers(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: iadd
       3: ireturn// Dalvik byte-code equivalent
.method public addTwoNumbers(II)I
    .registers 4
    .param p1, "a"    # I
    .param p2, "b"    # I    .line 6
    add-int v0, p1, p2    return v0
.end method        

??Now we have reached the main goal of this article. We can say that we have found the answers to the following questions:??

  • How does Android compilation process look like?
  • What happens under the hood with Java/Kotlin code?

?? I really hope that I’ve been able to make the Android compilation process easier for you to understand.

? But wait, there are two more questions that came up while I was learning about the compilation process. As a little extra, before I finish this article, I want to share those questions with you.

  • Why does Android have two virtual machines?
  • And why didn’t Google just use JVM?


??Let’s describe the difference between DVM and?ART

As mentioned earlier, ART was created to replace DVM. It was introduced in Android 4.4, also known as KitKat.

The major improvement was that ART uses a method called Ahead-Of-Time (AOT) compilation, while DVM uses a different method called Just-In-Time (JIT) compilation.

As we mentioned earlier, with JIT compilation, the app is compiled while it is running, which happens when the app starts up. This causes the app to take longer to start because it needs to be compiled every time the user opens it.

On the other hand, AOT compilation performs the compilation process when the app is being installed. It uses a tool called dex2oat that is built into the device. This tool takes the?.dex files of the app as input and generates a compiled version of the app that is specific to the device. This approach can make the app run much faster and perform better.

Since ART compiles the app’s code during installation, there is no need to translate it every time the user opens the app. This means that the CPU doesn’t have to work as hard as it does with the Just-In-Time (JIT) compilation used in Dalvik. When the CPU works less, it consumes less power, which is beneficial for the battery life of the Android device.

In addition to AOT compilation, ART introduced several other improvements. These include enhancements in Garbage Collection and improvements in Debug and Development capabilities. If you’re interested in delving deeper into these topics, I recommend referring to the official documentation for more information.


??? Why didn’t Google use JVM instead of creating another virtual?machine?

Google chose to abandon the JVM for a few reasons. They understood that the Android app runtime needed to work well on different devices with different capabilities. They also knew that apps needed to be isolated for security, performance, and reliability. However, using a virtual machine-based runtime wouldn’t allow them to achieve these goals with devices that had limited processing power and memory (RAM).

To solve these problems, Google decided to move away from the JVM and start using a different system called the Dalvik virtual machine (DVM) instead.

?? Difference between DVM and JVM

No alt text provided for this image
Figure 3: credit to aatul.me

Thank you for taking the time to read my article. I sincerely hope it provided you with helpful information. Please feel free to share your comments or provide any feedback you may have about the article.


Conclusion

Well, this is just a high-level diagram to show the Android app compilation process. I was not completely aware of this compilation process before, which I believe is a super important concept for all Android app developers to understand.

For more details about ART (which you don't need to know), you can refer to the official documentation?here.


?? Cheers???

?I’m also available for discussing anything related to Android, so if you’d like to chat, feel free to reach out to me on LinkedIn.???

?If you are interested in more articles on my Medium account, you can use this?Link. I hope that you’re having a great day.???

??Don’t forget to give a star or leave a comment if you found it useful.??

要查看或添加评论,请登录

Ahmed Samir Ahmed的更多文章

社区洞察

其他会员也浏览了