Appendix C. Art: The Android Runtime

Ever wonder how Android apps can run on so many kinds of devices? Android apps run in a virtual machine called the Android runtime (ART), not the Oracle Java Virtual Machine (JVM). This means that your apps are quicker to start on small, low-powered devices and run more efficiently. In this appendix, we’ll look at how ART works.

What is the Android runtime?

The Android Runtime (ART) is the system that runs your compiled code on an Android device. It first appeared on Android with the release of KitKat and became the standard way of running code in Lollipop.

ART is designed to run your compiled Android apps quickly and efficiently on small, low-powered devices. Android Studio uses the Gradle build system to do all the work of creating and installing apps for you, but it can be useful to understand what happens behind the scenes when you click the Run button. Let’s see what really goes on.

Note

You don’t need to understand the info in this appendix in order to create cool Android apps. So if you’re not into the nitty-gritty of what’s going on behind the scenes when an Android device runs an app, feel free to skip this appendix.

Previously, Java code ran on the Oracle JVM

Java has been around for a very long time, and compiled Java applications have almost always been run on the Oracle Java Virtual Machine (JVM). In that scenario, Java source code gets compiled down to .class files. One .class file gets created for every Java class, interface, or enum in your source code:

The .class files contain Java bytecodes, which can be read and executed by the JVM. The JVM is a software emulation of a Central Processing Unit (CPU), like the chip at the heart of your development machine. But because it’s emulated, it can be made to work on almost any device. That’s why Java code is designed to be written once, run anywhere.

So is that what happens on Android devices? Well...not quite. The Android Runtime performs the same kind of job as the JVM, but it does it in a very different way.

ART compiles code into DEX files

When you do Android development, your Java source code is compiled down into .dex files. A .dex file serves a similar purpose to a .class file, because it contains executable bytecodes. But instead of being JVM bytecodes, they are in a different format called Dalvik. DEX stands for Dalvik EXecutable.

Rather than creating a .dex file for each and every class file, your app will normally be compiled down into a single file called classes.dex. That single .dex file will contain bytecodes for all of your source code, and for every library in your app.

The DEX format can only cope with 65,535 methods, so if your app contains a lot of code or some large libraries, your file might need to be converted into multiple .dex files:

You can find out more about creating multi-DEX apps here:

https://developer.android.com/studio/build/multidex.html.

How DEX files get created

When Android builds your app, it uses a tool called dx, which stitches .class files into a DEX file:

It may seem a bit weird that the compilation process involves two stages of compilation: first to .class files, and then from .class files to the DEX format. Why doesn’t Google just create a single tool that goes straight from .java source code to DEX bytecodes?

For a while Google was developing a compiler called JACK and an associated linker called JILL that could create DEX code straight from Java code, but there was a problem. Some Java tools don’t just work at the source code level; they work directly with .class files, and modify the code that those files contain.

For example, if you use a code coverage tool to see which code your tests are actually running, the coverage tool will likely want to modify the contents of the generated .class files to add in additional bytecodes to keep track of the code as it’s executed. If you used the JACK compiler, no .class files were generated.

So back in March 2017, Google announced that it was shelving JACK, and was putting all of its efforts into making the dx tool work really well with the latest Java .class formats. This has the additional advantage that any new Java language features—so long as they don’t require new Java byte codes—will automatically be supported by Android.

DEX files are zipped into APK files

But Android apps aren’t shipped around as .dex files. There’s a whole bunch of other files that make up your app: images, sounds, metadata, and so on. All of these resources and your DEX bytecode is wrapped up into a single zip file called an Android Package or .apk file. The .apk file is created by another tool called the Android Asset Packing Tool, or aapt.

When you download an app from the Google Play Store, what actually gets downloaded is an APK file. In fact, when you run your app from Android Studio, the build system will first build an .apk file and then install it onto your Android device.

You may need to sign the .apk file

If you’re going to distribute your app through the Google Play Store, you will need to sign it. Signing an app package means that you store an additional file in the .apk that is based on a checksum of the contents of the .apk and a separately generated private key. The .apk file uses the standard jarsigner tool that comes as part of Oracle’s Java Development Kit. The jarsigner tool was created to sign .jar files, but it will also work with .apk files.

If you sign the .apk file, you will then also need to run it through a tool called zipalign, which will make sure that the compressed parts of the file are lined up on byte boundaries. Android wants them byte-aligned so it can read them easily without needing to uncompress the file.

Android Studio will do all of this for you if you choose Generate Signed APK from the Build menu.

So that’s how your app gets converted from Java source code into an installable file. But how does it get installed and run on your device?

Say hello to the Android Debug Bridge (adb)

All communication between your development machine and your Android device takes place over the Android Debug Bridge. There are two sides to the bridge: a command-line tool on your dev machine called adb, and a daemon process on your Android device called adbd (the Android Debug Bridge Daemon).

The adb command on your development machine will run a copy of itself in the background, called the ADB server. The server receives commands over network port 5037, and sends them to the adbd process on the device. If you want to copy or read a file, install an app, or look at the logcat information for an app, then all of this information passes back and forth across the debug bridge.

So when the build system wants to install your APK file, it does so by sending a command like this to the debug bridge:

adb install bitsandpizzas.apk

The file will then be transferred to a virtual device, or over a USB cable to a real device, and be installed into the /data/app/ directory, where it will sit waiting for the app to be run.

How apps come alive: running your APK file

When your app is run, whether it’s been started by a user pressing its launch icon or because the IDE has started it, the Android device needs to turn that .apk file into a process running in memory.

It does this using a process called Zygote. Zygote is like a half-started process. It’s allocated some memory and already contains the main Android libraries. It has everything it needs, in fact, except for the code that’s specific to your app.

When Android runs your app, it first creates a copy (a.k.a. fork) of the Zygote process, and then tells the copied process to load your application code. So why does Android leave this half-started process hanging around? Why not just start a fresh process from scratch for each app? It’s because of performance. It can take Android a long time to create a new process from scratch, but it can fork a copy of an existing process in a split second.

Android converts the .dex code to OAT format

The new app process now needs to load the code that’s specific to your app. Remember, your app code is stored in the classes.dex file inside your .apk package. So the classes.dex file is extracted from the .apk and placed into a separate directory. But rather than simply use the classes.dex file, Android will convert the Dalvik byte codes in classes.dex into native machine code. Technically, the classes.dex will be converted into an ELF shared object. Android calls this library format OAT, and calls the tool that converts the classes.dex file dex2oat.

The converted file is stored into a directory named something like this:

/data/dalvik-cache/data@[email protected]@[email protected]

This file can then be loaded as a native library by the application process, and the app appears on the screen.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.242.253