
Mono and Dalvik side by side
As you can recall from, Chapter 1, The Anatomy of an Android App, Android apps run within the Dalvik VM, and we now know that Mono apps run within the Mono CLR. So how does a Xamarin.Android app run? A simple answer is that it uses both the Mono CLR and the Dalvik VM. The following diagram depicts how the runtimes coexist:

Xamarin.Android applications use both Mono CLR and the Dalvik VM side by side and run on top of the Linux kernel. The .Net API resides as a part of the Mono CLR and provides a set of classes (for example, System.Data, System.Net, System.IO, and so on.) to access various device OS features. However, with .Net APIs, you cannot directly access most of the device-specific features, such as Audio, Telephony, OpenGL, and so on. They are made available as a part of the Android SDK or as Java API and can be accessed using the Android binding libraries. The following section covers more on the Android binding libraries.
Since Android 5.0 (Lollipop) release, the Dalvik VM was replaced by its successor, Android Runtime (ART). This means that now Xamarin.Android applications run with the Mono VM alongside ART. Both the runtimes work on top of the Linux kernel and expose a set of classes to access the device features.
So, how do the Mono CLR and Android Runtime (ART) work together in a Xamarin.Android app? The magic is accomplished through a concept called and a framework called the JNI.
The Java Native Interface
The Java Native Interface (JNI) is a framework that allows a non-Java code (such as C++ or C#) to call or be called by a Java code running inside a JVM. As you can see from the preceding diagram, JNI is a critical component in the overall Xamarin.Android architecture.
Peer objects
Peer objects are a pair of objects consisting of a managed object residing in the Mono CLR and a Java object residing in the Dalvik VM, which work together to perform the functions of a Xamarin.Android app.
Xamarin.Android is delivered with a set of assemblies called the Android binding libraries. Classes in the Android binding libraries correspond to the Java classes in the Android application framework, and the methods in the binding classes act as wrappers to call corresponding methods on Java classes. Binding classes are referred to as Managed Callable Wrappers (MCW). Anytime you create a C# class that inherits from one of these binding classes, a corresponding Java proxy class is generated at build time. The Java proxy contains a generated override for each overridden method in your C# class and acts as a wrapper to call the corresponding method on the C# class.
The creation of peer objects can be initiated from within the Dalvik VM by the Android application framework or from within the Mono CLR by the code you write in the overridden methods. A reference between the two peer objects is kept by each instance of a MCW and can be accessed through the Android.Runtime.IJavaObject.Handle
property.
The following diagram depicts how peer objects collaborate:

Xamarin.Android application packaging
In Chapter 1, The Anatomy of an Android App, we discussed Android packages (.apk
files). Xamarin.Android creates the .apk
files but also includes the following additional types of files:
- The C# code is stored as assemblies (containing IL) in the assembly folder of the archive.
- The Mono runtime is packaged as native libraries within the apk. The Xamarin.Android application must contain the native libraries for the desired Android architectures. If it doesn't contain the required libraries, the application will fail to run for those architectures.