Assemblies

Xamarin.Android includes a number of assemblies that constitute the MonoMobile Profile. The Assemblies page has more
information.

The bindings to the Android platform are contained in the Mono.Android.dll assembly. This assembly contains the entire
binding for consuming Android APIs and communicating with the Android runtime VM.

Binding Design

Collections

The Android APIs utilize the java.util collections extensively to provide
lists, sets, and maps. We expose these elements using the System.Collections.Generic interfaces in our binding. The
fundamental mappings are:

We have provided helper classes to facilitate faster copyless
marshaling of these types. When possible, we recommend using these provided
collections instead of the framework provided implementation, like List<T> or Dictionary<TKey, TValue>. The Android.Runtime implementations utilize a native Java collection
internally and therefore do not require copying to and from a native collection
when passing to an Android API member.

You can pass any interface implementation to an Android method accepting that
interface, e.g. pass a List<int> to the ArrayAdapter<int>(Context, int, IList<int>)
constructor. However, for all implementations except for the
Android.Runtime implementations, this involves copying the list from
the Mono VM into the Android runtime VM. If the list is later changed within the Android runtime (e.g.
by invoking the ArrayAdapter<T>.Add(T) method), those changes will not be visible in managed code. If a JavaList<int> were
used, those changes would be visible.

Rephrased, collections interface implementations that are not one of
the above listed Helper Classes only marshal [In]:

Events and Listeners

The Android APIs are built on top of Java and its components follow the Java
pattern for hooking up event listeners. This pattern tends to be cumbersome as
it requires the user to create an anonymous class and declare the methods to
override, for example, this is how things would be done in Android with
Java:

Note that both of the above mechanisms are available with Xamarin.Android.
You can implement a listener interface and attach it with
View.SetOnClickListener, or you can attach a delegate created via any of the
usual C# paradigms to the Click event.

When the listener callback method has a void return, we create API elements
based on an EventHandler<TEventArgs> delegate. We generate an
event like the above example for these listener types. However, if the listener
callback returns a non-void and non- boolean value, events and EventHandlers are not used. We
instead generate a specific delegate for the signature of the callback and add
properties instead of events. The reason is to deal with delegate invocation
order and return handling. This approach mirrors what is done with the Xamarin.iOS
API.

C# events or properties are only automatically generated if the Android
event-registration method:

Accepts only one parameter, the parameter type is an interface, the interface has only one method, and the interface name ends in Listener , e.g. View.OnClick Listener .

Furthermore, if the Listener interface method has a return type of boolean
instead of void, then the generated EventArgs subclass will contain
a Handled property. The value of the Handled property is used as the return
value for the Listener method, and it defaults to true.

We intend to add overloads for other methods and ctors to expose the
delegate-based connection. Also, listeners with multiple callbacks require some
additional inspection to determine if implementing individual callbacks is
reasonable, so we are converting these as they are identified. If there is no
corresponding event, listeners must be used in C#, but please bring any that you
think could have delegate usage to our attention. We have also done some
conversions of interfaces without the "Listener" suffix when it was clear they
would benefit from a delegate alternative.

All of the listeners interfaces implement the Android.Runtime.IJavaObject interface, because
of the implementation details of the binding, so listener classes must implement
this interface. This can be done by implementing the listener interface on a
subclass of Java.Lang.Object or any other wrapped Java object, such as an
Android activity.

The Runnable interface contains a single void method, run(). It therefore lends itself to binding in C# as a System.Action delegate. We have provided overloads in the binding
which accept an Action parameter for all API members which consume
a Runnable in the native API, e.g. Activity.RunOnUiThread() and View.Post().

We left the IRunnable overloads in place instead of replacing them since
several types implement the interface and can therefore be passed as runnables
directly.

Inner Classes

Java has two different types of nested classes: static nested classes and non-static classes.

Java static nested classes are identical to C# nested types.

Non-static nested classes, also called inner classes, are
significantly different. They contain an implicit reference to an instance of
their enclosing type and cannot contain static members (among other differences
outside the scope of this overview).

When it comes to binding and C# use, static nested classes are treated as
normal nested types. Inner classes, meanwhile, have two significant
differences:

The implicit reference to the containing type must be provided explicitly as a constructor parameter.

When inheriting from an inner class, the inner class must be nested within a type that inherits from the containing type of the base inner class, and the derived type must provide a constructor of the same type as the C# containing type.

Note how CubeWallpaper.CubeEngine is nested within CubeWallpaper, CubeWallpaper inherits from the
containing class of WallpaperService.Engine, and CubeWallpaper.CubeEngine has a constructor which takes the
declaring type -- CubeWallpaper in this case -- all as specified
above.

Interfaces

Java interfaces can contain three sets of members, two of which cause
problems from C#:

Methods.

Types.

Fields.

Java interfaces are translated into two types:

An (optional) interface containing method declarations. This interface has the same name as the Java interface, except it also has an ' I ' prefix.

An (optional) static class containing any fields declared within the Java interface.

Nested types are "relocated" to be siblings of the enclosing interface
instead of nested types, with the enclosing interface name as a prefix.

Changes in Xamarin.Android 1.9: Starting in Xamarin.Android 1.9, Java interface constants are duplicated in an effort to
simplify porting Java code. This should help improve porting Java code that
relies on android.provider interface constants.

In addition to the above types, there are four further changes:

A type with the same name as the Java interface is generated to contain constants.

Furthermore, consider the android.os.Bundle type, which implements the Java Parcelable interface. Since it implements the interface, all constants
on that interface are accessible "through" the Bundle type, e.g. Bundle.CONTENTS_FILE_DESCRIPTOR is a perfectly valid Java expression.
Previously, in order to port this expression to C# you would need to look at all
the interfaces which are implemented to see from which type the CONTENTS_FILE_DESCRIPTOR came from. Starting in Xamarin.Android 1.9,
classes implementing Java interfaces which contain constants will have a nested InterfaceConsts type, which will contain all the inherited interface
constants. This will allow translating Bundle.CONTENTS_FILE_DESCRIPTOR
to Bundle.InterfaceConsts.ContentsFileDescriptor.

Finally, types with a Consts suffix such as Android.OS.ParcelableConsts are now Obsolete, other than the newly
introduced InterfaceConsts nested types. They will be removed in Xamarin.Android 3.0.

Resources

Images, layout descriptions, binary blobs and string dictionaries can be
included in your application as resource files. Various Android APIs are designed to operate on the resource IDs instead of dealing with images,
strings or binary blobs directly.

For example, a sample Android app that contains a user interface layout
( main.axml), an internationalization table string
( strings.xml) and some icons ( drawable-*/icon.png)
would keep its resources in the "Resources" directory of the application:

The native Android APIs do not operate directly with filenames, but instead
operate on resource IDs. When you compile an Android application that uses
resources, the build system will package the resources for distribution and
generate a class called Resource that contains the tokens for each
one of the resources included. For example, for the above Resources layout, this
is what the R class would expose:

You would then use Resource.Drawable.icon to reference the drawable/icon.png file, or Resource.Layout.main to
reference the layout/main.xml file, or Resource.String.first_string to reference the first string in the
dictionary file values/strings.xml.

Constants and Enumerations

The native Android APIs have many methods that take or return an int that
must be mapped to a constant field to determine what the int means. In order to
use these methods, the user is required to consult the documentation to see
which constants are appropriate values, which is less than ideal.

In these cases, we endeavor to group related constants together into a .NET
enumeration, and remap the method to take the enumeration instead. By doing
this, we are able to offer IntelliSense selection of the potential values.

Note that this is a very manual process to figure out which constants belong
together, and which APIs consume these constants. Please file bugs for any
constants use in the API that would be better expressed as an enumeration.