File structure android. The internal device of Android systems

File system os android

so in this article, as you might have guessed from the title, we’ll talk about the general structure. file system  android Description of main directories, formatting methods, backup  and so on. The article is mainly aimed at beginners. I hope the rest will be interesting to read.
linux file system structure



android does not have many of the usual disks - such as with or d. The root of our file system is: "". all other directories are attached to the root directory. Consider some of them:

system- by the name you can already guess that the system files are located here (something like we can see in the OS from Microsoft c: windows). The files in this folder are unchangeable by default. They are intended for the functioning of the operating system. Also here are the built-in applications that are built into the OS. If we get root rights then we can make our changes in this directory. However, it should be done carefully for deleted files  and folders will not recover by themselves. In this case, only a flashing or backup will help us. Something interesting can be found in the folder systemmedia. In the archive bootanimation.zip  There are pictures that make up the animation when the device is turned on. Even in the root of the system folder, you can find the file build.prop  which contains a lot of settings, from the description of the device to the density of the screen (for configuring this config there are many third-party applications).screen


Data  - Unlike systems, stored files are stored here. In under categories app  Just stored apk installed by us programs. screen

If we need an apk file of any application, then we can easily find it there. And in datadata  data of these installed programs.
Mnt  -In this section, user memory is mounted (for example, if you install a flash card). Thus, if we place our txt file in the root of the flash card, then the full path will look like this " mntsdcard file". The built-in disk for smartphones without support for memory cards is also mounted here. screen


How to do wipe (reset) on android


there are several ways to format. About several of them below
1. reset via settings. Go to settings \u003e\u003e restore and reset \u003e\u003e reset settings. Clears all settings and removes the set by. Before this, you can backup some settings by ticking the corresponding item. After the reboot, the device will ask whether to restore this data.
screen


2. reset via recovery.  Useful in the situation when the device does not turn on. You will need root access and an appropriately installed recovery. Depending on the installed recovery, the location of the items may vary. I have a point advanced wipe. Contains:
dalvik cache  - cache formatting virtual machine  dalvik.
System- formatting the system partition.
Data  - delete all third-party applications in the device's memory as well as user settings.
cache - cache removal
format sdcard  - formatting the memory card. Delete all that is on the memory card.
format sd-ext- formatting the section on the memory card (if such a section was created. For example, to mount the script of the referring application when installed on the card).
3. formatting using the service code.  If you dial * 2767 * 3855 #. immediately after dialing, a reset will occur. Be careful.
So for example, deleting the contents of a folder datadata  we will remove the settings and application data but not the applications themselves. This can also be done from the settings of the "delete data" application. When you delete the folder, the date will be deleted. installed applications.
Wishes, amendments, additions to the article, please leave in the comments or to me in a personal. article will be supplemented. Thank you readers, success.
-----------------
  You can leave comments in the Article Catalog section. middleware, is a set of libraries (Libraries), designed to solve common problems that require high efficiency. That is, it is this level that is responsible for providing implemented algorithms for higher levels, supporting file formats, encoding and decoding information (for example, multimedia codecs), drawing graphics, and much more. Libraries are implemented in C / C ++ and compiled for a specific hardware  devices with which they are supplied by the manufacturer in a pre-installed form.

Here are some of the low-level libraries:

  1. Surface Manager - the Android OS uses a composite window manager like Compiz (Linux), but more primitive. Instead of drawing graphics directly to the display buffer, the system sends incoming drawing commands to the voice-over buffer, where they accumulate together with others, composing a certain composition, and then displayed to the user on the screen. This allows the system to create interesting seamless effects, realize window transparency and smooth transitions.
  2. Media Framework - libraries implemented on the basis of PacketVideo OpenCORE. With their help, the system can record and play audio and video data, as well as output static images. Many popular formats are supported, including MPEG4, H.264, MP3, AAC, AMR, JPG and PNG. In the future, OpenCORE will be replaced by a simpler framework, Stagefright.
  3. SQLite is a lightweight and productive relational database engine used in Android as the main database engine.
  4. 3D libraries - used for highly optimized drawing of 3D graphics, using hardware acceleration if possible. Their implementations are based on the OpenGL ES 1.0 API.
  5. FreeType is a library for working with bitmaps, as well as for rasterizing fonts and performing operations on them. This is a high-quality engine for fonts and text display.
  6. LibWebCore - libraries of the well-known browser engine WebKit, also used in desktop google browsers  Chrome and Apple Safari.
  7. SGL (Skia Graphics Engine) - an open engine for working with 2D graphics. The graphics library is a product of Google and is often used in their other programs.
  8. SSL - libraries to support the same cryptographic protocol based on OpenSSL.
  9. libc is a library of standard C language calls, an analogue of glibc (GNU libc from Linux) for small devices. It is called Bionic.


Fig. 1.5.

At the same level is the Android Runtime - application runtime environment. Its key components are a set of standard libraries and virtual machine Dalvik. Each application in the Android OS runs in its own copy of the Dalvik virtual machine. Thus, all running processes are isolated from the operating system and from each other. The architecture of the Android Runtime is such that the work of the programs is carried out strictly within the framework of the virtual machine environment. Due to this, the core of the operating system is protected from possible harm from its other components. Therefore, the code with errors or malware will not be able to spoil the Android OS and the device based on it. Such a protective function, along with the execution of the program code, is one of the key for the Android Runtime.

The level above is the Application Framework, sometimes called the application framework level. It is through application frameworks that developers get access to the API provided by lower-level system components. In addition, thanks to the framework architecture, any application is provided with the already implemented capabilities of other applications that are allowed to access. The basic set of services and systems that underlie each application and are part of the framework include:

  1. A rich and extensible set of views (Views) that can be used to create visual components of applications, such as lists, text fields, tables, buttons, or even an embedded web browser.
  2. Content Providers that manage data that some applications open to others so they can use them for their work.
  3. A resource manager (Resource Manager) that provides access to resources that do not carry code, such as string data, graphics, files, and others.
  4. Notification Manager, through which all applications can display their own notifications for the user in the status bar.
  5. The Activity Manager, which manages the life cycles of applications, stores data on the history of work with activities, and also provides a navigation system for them.
  6. Location Manager (location manager), allowing applications to periodically receive updated data on the current geographical location of the device.

At the top of the Android software stack lies the Applications level (Applications). This includes a set of basic applications, which is preinstalled on the Android OS. For example, it includes a browser, mail client , program for sending SMS, maps, calendar, contact manager and many others. The list of integrated applications may vary depending on the device model and android version  . And besides this basic set, the level of applications includes all applications for the Android platform, including those installed by the user.

As a rule, Android applications are written in Java, but there is an opportunity to develop programs in C / C ++ (using the Native Development Kit). Exotics can be called using Basic (using Simple) and other languages. You can also create your own programs using application designers, such as App Inventor.

1.6. Kernel Features

The kernel is the most important part of the Linux OS, and unlike its other parts, it was almost completely transferred to the Android OS. However, in the process of transferring about 250 patches were applied to the core.

In the Android OS kernel, it was decided to abandon the means of interprocess communication of the Linux OS and instead create a single mechanism called Binder. Binder allows you to call the methods of one process from another process, passing arguments to them and getting the result, just as the methods are called within the same process. Binder does this job with minimal memory usage.

To enable debugging on small devices, debugging information has been added to the kernel. serial port  and implemented support for the logcat command.

Big changes touched work with memory. The traditional Linux shared memory shmem has been replaced by ashmem. The same problem, but at the level of physical memory, is solved using the pmem driver. A special out of memory handler, called Viking Killer, has been added; in the simplest case, it just kills the process, but more complex rules can be set.

New security settings have been added to the network stack; file system support for YAFFS2 flash drives is included in the kernel.

1.7. Java machine Dalvik

Dalvik Virtual Machine is part of the Android mobile platform. it virtual machinesponsored by Dan Bronstein. It spreads like free software  under BSD-compatible Apache 2.0 license. In many ways, this fact played a role in google solution abandon JME (Java Micro Edition), which would need to get a license from Sun. Therefore, the corporation, whose goal was to create an open operating system, developed its own virtual machine.

Unlike most virtual machines (the same Java Virtual Machine) that are stack-oriented, Dalvik is register-oriented, which cannot be called a standard solution. On the other hand, it is very well suited to work on RISC architecture processors, which include ARM processors, which are very widely used in mobile devicesoh.

Dalvik was designed specifically for the Android platform. The fact that the platform builds all processes as isolated, each running in its own address space, was taken into account. Virtual machine  optimized for low memory consumption and work on mobile hardware. Starting with Android 2.2., Dalvik uses the JIT (Just-in-Time) compilation. As a result of these features, fast and productive virtual machinethat can not affect the operation of applications in general.

Dalvik uses its own bytecode. When developing an Android application, they are translated by the compiler into a special machine-independent low-level code. When executed on a platform, Dalvik interprets and executes such a program.

In addition, Dalvik is able to translate Java bytecodes into native format codes and also execute them in its virtual environment. The program code is written in Java, and after compilation everything. class files are converted to .dex format (suitable for interpretation in Dalvik) using the special utility dx, included in the Android SDK.

1.8. Bionic

Bionic is a standard C language library distributed under the BSD license (Berkeley Software Distribution? Distribution system software  in source code, created for the exchange of experience between educational institutions) and developed by Google for Android. In bionic, there are some non-Android POSIX functions that are available in the full glibc implementation.

The main differences bionic:

  1. BSD license: Android uses the Linux kernel, which is under the GNU General Public License (GPL), but Google wanted to isolate Android applications from the effects of the GPL. The GNU libc, which is commonly used with the Linux kernel, is under the GNU LGPL license, as an alternative to uClibc.
  2. small size: bionic object code is much smaller (about 2 times) than glibc and slightly smaller than uclibc.
  3. bionic is designed for processors with relatively low clock speeds.
  4. a truncated but effective implementation of the POSIX threads.

1.9. Overview of Java Application Programmer Interfaces

For Android application programmer - a set of interfaces in the Java language. Consider how it is organized. At the heart of the set are packages that are included in the Java language standard, such as java.util, java.lang, java.io. They are on any platform where java applications can run, and are non-specific for Android. Extensions adjoin them, which are not included in the standard of the language, but de facto have long been standard - javax.net, javax.xml packages.

Also included in Android less common java extensions   - package org.apache.http, the most solid implementation of the HTTP protocol. The org.json package is responsible for serializing JavaScript objects and supporting AJAX technology. The org.w3c.dom package provides the document object model

    In certain models of tablets based on the Android platform, some components from the above list may be missing.

    All "android" tablets are controlled by one of the versions of the mobile operating system from Google. However, older versions may not support some of the modern applications.

    All versions of the most popular mobile operating system have a common basis. We can imagine operating system  Android as a multilayer structure. Computer engineers call this the software stack. The elements at the top of the stack are what the user sees during his interaction with the operating system. On the bottom of the stack are those parts of the operating system that interact directly with the hardware of the device.

    So, at the lowest level are the hardware components themselves: processors, sensors, wires, and printed circuit boards. The next layer is the core of the operating system. The kernel is sometimes also called embedded (or proprietary) software. More commonly known is the English definition of “firmware”. This software controls the hardware resources of the device, controls them and their distribution.

    This part of the operating system "translates" into the language of hardware components those commands that the user gives through a convenient graphical interface. A sample kernel for Android is the open source operating system Linux 2.6.

    Android libraries are located above the operating system kernel. They are sets of instructions that a device follows in processing various types of data. An example is the orientation library in three-dimensional space. It contains all the instructions that the Android device requires in order to recognize changes in its position in space and respond to them.

    At the same level of the software stack are the root libraries needed to support applications written in the Java language. Java is a programming language from Sun Microsystems. More recently, Java-enabled phones have been very common. Currently, they are increasingly being replaced by smartphones.

    Android virtual machine is located at the same level of the operating system software stack. This piece of software is creating a virtual operating environment, which is also otherwise called a virtual operating environment. A virtual machine simulates a physical device with a separate operating system. Google designed this layer so that each application running on the Android operating system functions as a separate process. Thus, if one of the running processes fails, the rest will remain unaffected. The virtual machine also plays the role of a memory manager.

    The next level is the application framework. It is the basis for all applications "android" device. The application infrastructure is the link between applications and the rest of the operating system.

    Google recommends that developers create applications that interact with this layer as part of the application programming interface () developed by the search giant operating system. Developers need only to familiarize themselves with these API-related rules. They don't need to think about technical specifications  every "android" tablet.

    The top level of the software stack contains the user interface and all applications of the android tablet. This part of the operating system is constantly seen by the user. But behind this attractive and colorful layer hides a lot of boring, and interesting only to specialists of the code.

    Like any other operating system, and other hardware resources of the tablet.

    Based on computer.howstuffworks.com

# facts | How does Android work?   Oleg Dovbnya

  Have you ever wondered how fastboot or ADB work? Or why a smartphone under running Android  almost impossible to turn into a brick? Or maybe you have long wanted to know where the magic of the Xposed framework lies and why do you need the /system/etc/init.d boot scripts? What about the recovery console? Is it a part of Android or a thing in itself, and why is the usual recovery not suitable for installing third-party firmware? Answers to all these and many other questions you will find in this article.

How Android works

  Learn about hidden features software systems  You can, having understood the principle of their work. In some cases, this is difficult to do, since the system code may be closed, but in the case of Android we can explore the entire system up and down. In this article I will not talk about all the nuances of the work of Android and will focus only on how the OS starts and what events take place in the interval between pressing the power button and the appearance of the desktop.

Along the way, I will explain what we can change in this chain of events and how custom firmware developers use these features to implement things like OS tuning, expanding the space for storing applications, connecting swap, various customizations and much more. All this information can be used to create your own firmware and implement various hacks and modifications.

Step one. ABOOT and partition table

  It all starts with the primary loader. After power on, the system executes the bootloader code recorded in the device’s permanent memory. Then it transfers control to the bootloader aboot with built-in support for the fastboot protocol, but the manufacturer of the mobile chip or smartphone / tablet has the right to choose any other bootloader to his taste. For example, the company Rockchip uses its own, incompatible with fastboot bootloader, for reprogramming and controlling which one has to use proprietary tools.

The fastboot protocol, in turn, is a PC bootloader management system that allows you to perform such actions as unlocking the bootloader, flashing the new kernel and recovery, installing the firmware, and many others. The meaning of the existence of fastboot is to be able to restore the smartphone to its initial state in a situation when all other means do not work. Fastboot will remain in place, even if, as a result of experiments, you erase from your smartphone all sections of NAND memory containing Android and recovery.

After receiving control, aboot checks the partition table and transfers control to the kernel stitched to the partition named boot, after which the kernel extracts a RAM image from the same partition into memory and starts downloading either Android or the recovery console. NAND-memory in Android devices is divided into six conditionally mandatory sections:

  • boot - contains a kernel and a RAM disk, usually about 16 MB in size;
  • recovery - recovery console, consists of a kernel, a set of console applications and a configuration file, size 16 MB;
  • system - contains Android, in modern devices has a size of at least 1 GB;
  • cache - is designed to store cached data, is also used to save the firmware during the OTA-update and therefore has a size similar to the size of the system partition;
  • userdata - contains settings, applications and user data, he is given all the remaining space of the NAND-memory;
  • misc - contains a flag that determines in which mode the system should boot: Android or recovery.
In addition to them, there may also be other sections, but the overall markup is determined at the design stage of the smartphone and, in the case of aboot, is stitched into the loader code. This means that: 1) the partition table cannot be killed, since it can always be restored using the fastboot oem format command; 2) to change the partition table, you will have to unlock and reflash the bootloader with the new parameters. From this rule, however, there are exceptions. For example, the same Rockchip boot loader stores information about partitions in the first block of NAND memory, so you do not need a bootloader flashing to change it.

Part of the loader code defining the partition table


  Particularly interesting section misc. There is an assumption that it was originally created to store various settings regardless of the main system, but in this moment it is used only for one purpose: to indicate to the loader, from which partition the system should be loaded - boot or recovery. This feature, in particular, uses the ROM Manager application to automatically reboot the system in recovery with the automatic installation of the firmware. On its basis, the Ubuntu Touch dual boot mechanism is built, which flushes the Ubuntu bootloader in recovery and allows you to control which system to load next time. Stehr misc section - Android is loaded, filled with data - recovery is loading ... that is, Ubuntu Touch.

Step two. Boot section

  If the misc section does not have a boot flag in recovery, aboot transfers control to the code located in the boot section. It is nothing like the Linux kernel; it is located at the beginning of the section, and immediately followed by a RAM disk image packed with cpio and gzip archivers, containing the necessary directories for Android, init init system and other tools. There is no file system on the boot partition, the kernel and the RAM disk simply follow each other. The contents of the RAM disk are:

  • data - directory for mounting the section of the same name;
  • dev - device files;
  • proc - procfs is mounted here;
  • res - a set of images for charger (see below);
  • sbin - a set of utility tools and daemons (adbd, for example);
  • sys - sysfs is mounted here;
  • system - directory for mounting the system partition;
  • charger - an application to display the charging process;
  • build.prop - system settings;
  • init - initialization system;
  • init.rc - initialization system settings;
  • ueventd.rc - settings for the uventd daemon that is part of init.
This, if I may say so, is the skeleton of the system: a set of directories for connecting file systems from NAND-memory partitions and an initialization system that will do the rest of the work on loading the system. The central element here is the init application and its init.rc config, which I will discuss in more detail later. In the meantime, I want to draw attention to the files charger and ueventd.rc, as well as the directories sbin, proc and sys.

The charger file is a small application whose only task is to display the battery icon. It has no relation to Android and is used when the device is connected to the charger in the off state. In this case, Android does not boot, and the system simply loads the kernel, connects the RAM disk and starts the charger. The latter displays the battery icon, the image of which in all possible states is stored in ordinary PNG files inside the res directory.

The ueventd.rc file is a config file that determines which device files in the sys directory should be created during the system boot phase. In core based Linux systems  the hardware is accessed through special files inside the dev directory, and the ueventd daemon, which is part of init, is responsible for creating them on Android. In a normal situation, it works automatically, accepting commands to create files from the kernel, but some files need to be created independently. They are listed in ueventd.rc.

The sbin directory in the Android stock usually contains nothing but adbd, that is, the ADB daemon, which is responsible for debugging the system from a PC. It starts at an early stage of loading the OS and allows you to identify possible problems  at the stage of OS initialization. In the custom firmware in this directory, you can find a bunch of other files, for example mke2fs, which may be required if the partitions need to be reformatted into ext3 / 4. Also modery often put there BusyBox, with which you can call hundreds of Linux-commands.

The proc directory for Linux is standard; in the next boot steps, init will connect procfs to it, a virtual file system that provides access to information about all the processes in the system. The system will connect to the sys directory sysfs, which opens access to information about the hardware and its settings. Using sysfs, you can, for example, send a device to sleep or change the power saving algorithm used.

The build.prop file is designed to store low-level android settings. Later, the system will reset these settings and overwrite them with values ​​from the currently unavailable system / build.prop file.

The root section of the set-top box OUYA


Step two, alternative. Recovery section

In case the recovery boot flag in the misc section is set or the user has turned on the smartphone while holding the volume down key, aboot will transfer control to the code located at the beginning of the recovery section. Like the boot section, it contains a kernel and a RAM disk, which is unpacked into memory and becomes the root of the file system. However, the contents of the RAM disk are somewhat different here.

Unlike the boot partition, which acts as a transitional link between different stages of the OS boot, the recovery partition is completely self-contained and contains a miniature operating system that is not related to Android. The recovery has its own kernel, its own set of applications (commands) and its own interface, which allows the user to activate the service functions.

In the standard (stock) recovery, there are usually only three such functions: installation of firmware-signed key signed by the manufacturer of the smartphone, wipe and reboot. The modified third-party recovery, such as ClockworkMod and TWRP, features much more. They can format file systems, install firmware signed by any keys (read: custom), mount file systems on other partitions (for OS debugging purposes) and include script support that automates the firmware process and many other functions.

Using scripts, for example, you can make sure that after downloading the recovery automatically finds the necessary firmware on the memory card, installs them and reboots into Android. This feature is used by the tools ROM Manager, auto-flasher, as well as the automatic update mechanism of CyanogenMod and other firmware.

Custom recovery also supports backup scripts located in the /system/addon.d/ directory. Before flashing, recovery checks for scripts and executes them before flashing. Thanks to these scripts, gapps do not disappear after installation. new version  firmware.

Step three. Initialization

So, after receiving control, the kernel connects the RAM disk and, after the initialization of all its subsystems and drivers is completed, it initiates the init process, from which Android initialization begins. As I said before, init has a configuration file, init.rc, from which the process will know what it should do to raise the system. In modern smartphones, this config has an impressive length of several hundred lines and is also equipped with a trailer of several daughter configs that are connected to the main one with the help of the import directive. Nevertheless, its format is quite simple and in fact is a set of commands, divided into blocks.

Each block determines the stage of loading or, in the language of Android developers, action. The blocks are separated from each other by the on directive followed by the name of the action, for example, on early-init or on post-fs. The block of commands will be executed only if the trigger of the same name is triggered. As booting starts, init will activate the early-init, init, early-fs, fs, post-fs, early-boot, and boot triggers in turn, thus starting the appropriate command blocks.

Part of the init.rc config from CyanogenMod


  If the configuration file pulls several more configs listed at the beginning (and this is almost always the case), the same-named command blocks inside them will be merged with the main config, so that when the trigger trigger, init executes commands from the corresponding blocks of all files. This is done for the convenience of generating configuration files for several devices, when the main config contains commands that are common to all devices, and specific for each device are written into separate files.

The most notable of the additional configs is named initrc.device_name.rc, where the device name is determined automatically based on the contents of the ro.hardware system variable. This is a platform-specific configuration file that contains command blocks specific to a particular device. In addition to the commands responsible for tuning the kernel, it also contains about the following command:

mount_all ./fstab.device_name

It means that init should now mount all the file systems listed in the ./ fstab.device_name, which has the following structure:

device_name (of section) mount_point mount_file option_fs other options

It usually contains instructions for connecting file systems from internal NAND partitions to the / system (OS), / data (application settings) and / cache (cached data) directories. However, by slightly changing this file, we can force init to load the system from the memory card. It is enough to split the memory card into three 4 sections: 1 Gb / ext4, 2 Gb / ext4, 1 Gb / ext4 and the remaining space fat32. Next you need to determine the names of the sections of the memory card in the / dev directory (for different devices  they differ) and replace the original device names in the fstab file.

Typical fstab file contents


  At the end of the boot init block, you will most likely encounter the class_start default command, which will inform you that next you should start all the services listed in the config that are related to the default class. The description of services begins with the service directive, followed by the name of the service and the command that must be executed to start it. Unlike the commands listed in the blocks, the services should work all the time, so throughout the life of the smartphone, init will hang in the background and keep an eye on it.

Modern Android includes dozens of services, but two of them have a special status and define the entire system life cycle.

Step Four. Zygote and app_process

  At a certain stage of loading, init will encounter at the end of the config something like this unit:

service zygote / system / bin / app_process -Xzygote / system / bin --zygote --start-system-server
   class default
   socket zygote stream 660 root system
   onrestart write / sys / android_power / request_state wake
   onrestart write / sys / power / state on
   onrestart restart media
   onrestart restart netd

This is a description of the Zygote service, a key component of any Android system that is responsible for initialization, start system services, start and stop user applications and many other tasks. Zygote is launched using a small application / system / bin / app_process, which can be seen very well on the piece of the config above. The app_proccess task is to start the Dalvik virtual machine, whose code is located in the /system/lib/libandroid_runtime.so shared library, and then run Zygote on top of it.

When all this is done and Zygote gets control, it starts building the execution environment of Java applications by loading all the Java classes of the framework (there are now more than 2000 of them). Then it starts the system_server, which includes most of the high-level (written in Java) system services, including the Window Manager, the Status Bar, the Package Manager and, most importantly, the Activity Manager, which in future will be responsible for receiving start and end signals applications.

After that, Zygote opens the socket / dev / socket / zygote and goes to sleep, waiting for the data. At this time, the previously launched Activity Manager sends the broadcast content Intent.CATEGORY_HOME to find the application responsible for creating the desktop, and gives it the name Zygote via a socket. The latter, in turn, forks and runs the application on top of the virtual machine. Voila, we’ve got a desktop on the screen, a found Activity Manager and a running Zygote, and a status bar, launched by system_server within the Status Bar service. After tapping on the icon, the desktop will send an intent with the name of this application, it will be accepted by the Activity Manager and will send a command to start the application to the Zygote daemon

All this may look somewhat incomprehensible, but the most important thing is to remember three simple things:

System services and kernel threads


findings

  In many ways, Android is very different from other operating systems, and it’s impossible to figure it out. However, if you understand how everything works, there are simply endless possibilities. Unlike iOS and Windows phone, the operating system from Google has a very flexible architecture that allows you to seriously change its behavior without the need to write code. In most cases, it is enough to tweak the necessary configs and scripts.
  • Transfer

In this article we will look at the architecture of Android applications.

Frankly, I find the official Google on this topic not very useful. Responding in detail to the question “how”, she doesn’t explain at all what and why. So, here is my version, and I hope it will bring some clarity. Yes, by the way, I fully approve of reading Google articles, because they contain useful information, which I do not intend to repeat.

Android OS architecture - a bit of history

  As is often the case in IT, many things cannot be explained in isolation from the history of the emergence of specific software. That is why we must turn to the origins of the Android OS.

The development of the Android OS was launched in 2003 by the young company Android Inc. In 2005, this company was bought by Google. I believe that the main features of the Android architecture were identified during this period. This is not only the credit of Android Inc; Google’s architectural concepts and financial resources have had a decisive influence on Android’s architecture. Next I will give a few examples.

If you remember, 2003-2005 was marked by increased attention to AJAX applications. I think this had a fundamental impact on the architecture of Android: in many aspects it is closer to the architecture of a typical AJAX application than to the desktop GUI application written in Java, C #, C ++, VB, and so on.

I do not know why it happened. My guess was someone from Google invented at a time when rich Internet applications (Rich Internet Applications, RIA) in the spirit of Google Docs or Gmail were considered to be the solution to all problems. In my opinion, this idea can not be called neither good nor bad. Just remember that Android applications are very different from desktop ones.

The influence of the architectural philosophy of Eclipse is noticeable in choosing the principle of GUI implementation, which is more like SWT than Swing.

In the standards for the design of the Android code there is a “Hungarian notation”, born within the walls of MS. It can be assumed that the person who wrote these standards was previously engaged in the development under Windows.

Android architectural levels
  The Android operating system has three very different and highly separated levels:
  1. It is based on a modified and trimmed version of Linux, as I mentioned in one of my previous articles.
  2. Above the Linux level is the application infrastructure layer, which contains the Dalvik virtual machine, a web browser, a SQLite database, some infrastructure crutches, and a Java API.
  3. And finally, the level of Google-written Android applications. Generally speaking, they are an extension of the infrastructure level, since the developer can use these applications or parts of them as building blocks for their own development.
  Consider these layers one by one and in more detail.

Linux level

  Imagine that you are an architect in a young company. You must develop an OS for a new type of device. What are you going to do?

Roughly speaking, you have two ways: to implement your own ideas, starting from scratch, or use the existing OS and adapt it to your devices.

Implementing from scratch always sounds exciting to programmers. At these moments, we all believe that this time we will do everything better than others do, and even better than we ourselves did before.

However, this is not always practical. For example, the use of the Linux kernel has significantly reduced the cost of development (perhaps somewhere already excessively large). Agree, if someone decides to create something resembling the Linux kernel in its current state, it will need several million dollars.

If you are in charge of Android Inc, then by definition you cannot have that much money. If you run Google, then you will find that kind of money, but you will most likely think twice before spending it on creating your own OS. You will also spend several years before you reach the current state of Linux; several years of delay may be too late to enter the market.

In this situation, Apple decided to build a Mac OS based on Free BSD. Android Inc decided to use Linux as the basis for Android. Both BSD and Linux sources are freely available and provide a good basis for any development, be it Apple or Google.

But at that time it was impossible to launch standard Linux on a mobile device (now this is no longer the case). The devices had too little RAM and non-volatile memory. The processors were significantly slower compared to the processors of computers where Linux is commonly used. As a result, Android developers decided to minimize system requirements  Linux.

If we consider Linux on high levelthen it is a combination of the core (without which it cannot be avoided) and many other optional parts. You can even run one core, without anything else. So, Google is forced in any case to use the Linux kernel as part of the Android OS. In addition, optional parts were considered and the most necessary were selected. For example, the IPTables network firewall and the Ash shell were added. It is curious that it was Ash who was added, not Bash, despite the fact that the latter is an order of magnitude more powerful; this decision was probably based on the fact that Ash is less resource intensive.

Android developers have modified the Linux kernel, adding support for hardware used in mobile devices and, more often, inaccessible on computers.

The choice of Linux as the basis had a huge impact on all aspects of the Android OS. Building Android, in fact, is a variation of the Linux build process. Android code  is running git (a tool designed to manage linux code). And so on.

Let it all be interesting, but you will most likely never touch all these specific moments until your goal is to develop Android applications. The only exception may be a review of the file system using the ash commands. The main thing that you should know when developing applications for Android is the level of application infrastructure.

You may ask how to be if you need to develop a native Android application? Google strongly discourages doing this. Technically, of course, this is possible, but in the future you will not be able to distribute this application in the normal way. So think twice before starting native Android development, unless of course you are working on the Android Open Source Project (AOSP), i.e. Android OS itself.

Application Infrastructure Level

  Despite some similarities Apple iOS  and Android OS, there are significant differences between the architectural solutions at the infrastructural level of both OSs.

Apple decided to use Objective-C as a programming language and runtime environment. iOS apps. Objective-C looks like a more or less natural choice for an OS based on Free BSD. You can think of Objective-C as regular C ++ with a custom preprocessor that adds some specific linguistic constructs. Why it is impossible to use standard C ++ on which Free BSD is written? I think the reason is that Apple is trying to do everything in its “Apple” style.

The basic idea is that iOS applications are written more or less in the same language as the OS behind them.

Android applications are very different in that sense. They are written in Java, and this is a completely different technology than C ++ (although the syntax is inherited from C ++).

I think the main reason is that the same application needs to work on different hardware. This problem only occurs for the Android OS; The guys from Apple have no such problem. iOS only works on its own production equipment, and Apple fully controls the entire process. For Android, the opposite is true: Google does not control hardware manufacturers. For example, the Android OS runs on x86, ARM and Atom processors (in the comments, x86 includes Atom, and Android runs on x86, ARM, PPC and MIPS - translator's note). At the binary level, these architectures are incompatible.

If the architects of the Android OS chose the same path as the architects from Apple, Android developers would have to distribute several versions of the same application at the same time. This would be a serious problem that could lead to the collapse of the entire Android project.

In order for the same application to work on different hardware, Google used container-based architecture. In this architecture, the binary code is executed by a software container and is isolated from the details of the specific hardware. Examples are familiar to all - Java and C #. In both languages, the binary code does not depend on the specific hardware and is executed by the virtual machine.

Of course, there is another way to achieve hardware independence at the binary code level. As one option, you can use a hardware emulator, also known as QEMU. It allows you to emulate, for example, a device with an ARM processor on the x86 platform and so on. Google could use C ++ as a language for developing applications inside emulators. Indeed, Google uses this approach in its Android emulators, which are based on QEMU.

It is very good that they did not follow this path, because then someone would have to run the OS on an emulator, which requires much more resources, and, as a result, the speed of work would decrease. For achievement best performance  emulation was left only where it could not be avoided, in our case in Android applications.

Be that as it may, Google has decided to use Java as the main language for developing applications and their environment.

I think it was a critical architectural solution that put Android apart from the rest of the Linux-based mobile OSs that are currently available. As far as I know, none of them have binary compatibility at the application level. Take for example MeeGo. It uses C ++ and the Qt framework; Despite the fact that Qt is cross-platform, the need to do different builds for different platforms does not disappear.

Choosing Java, you had to decide which virtual machine (JVM) to use. Due to limited resources, using standard JVM was difficult. The only possible choice was to use a Java ME JVM developed for mobile devices. However, the happiness of Google would be incomplete without developing its own virtual machine, and Dalvik VM appeared.

Dalvik VM differs from other Java virtual machines in the following:

  • It uses a special DEX format for storing binary codes, as opposed to the JAR and Pack200 formats, which are the standard for other Java virtual machines. Google has said that the DEX binaries are smaller than the JAR. I think they might as well have used Pack200, but they decided to go their own way.
  • Dalvik VM is optimized to run multiple processes simultaneously.
  • Dalvik VM uses a register-based architecture against stack architecture in other JVMs, which leads to an increase in execution speed and a decrease in the size of binaries.
  • It uses its own set of instructions (rather than the standard JVM bytecode).
  • It is possible to launch (if necessary) several independent Android applications in one process.
  • Running an application can span multiple Dalvik VM processes in a “natural way” (later we will discuss what this means). To support this, added:
    • A special object serialization mechanism based on the Parcel and Parcelable classes. Functionally, they pursue the same goals as Java Serializable, but as a result, the data is smaller and potentially more tolerant of versioning class changes.
    • A special way to make inter-process calls (inter process calls, IPC), based on Android Interface Definition Language (AIDL).
  • Prior to Android 2.2, Dalvik VM did not support JIT compilation, which was a serious performance hit. Starting with version 2.2, the speed of execution of frequently used applications