Custom controls in the Xamarin Android Designer
Published: 2019-03-31 15:26:55

---
title: Custom controls in the Xamarin Android Designer
published: true
tags: 
canonical_url: https://blog.neteril.org/blog/2016/12/17/custom-controls-xamarin-android-designer/
---

_aka an introductory look at the internals of our Android ecosystem_

In the latest stable release of the Xamarin platform, one specific feature I worked on is custom controls support in the Android designer (both Mac with Xamarin Studio and Windows on Visual Studio).

Our iOS designer has long enjoyed this kind of support, actually from day 1. Being part of that team at the time, I can confirm we were quite excited (and relieved!) to see that pie chart renders on stage when Miguel [introduced the feature](https://www.youtube.com/watch?v=XVdqjGDkv9s#t=58m) at Evolve 2013:

![iOS designer custom controls](https://blog.neteril.org/wp-content/uploads/android-designer-custom-controls/ios-designer.png)

However, because the rendering strategy is quite different between the two designers, attaining the same level of support for custom controls on Android was much more challenging.

In this post I want to highlight how the Android designer and, more generally, Xamarin.Android work and how implementing custom controls fitted into this.

### Designer Architecture

The Android designer is roughly split into two main parts. The first one is written in C# and constitute the bulk of the code. It’s a cross-IDE library that implements all the visual pieces of a modern designer like a surface canvas or a property panel and all the plumbing to make those work including a full DOM for Android layouts.

The second part is implemented in Java and, unlike the previous part that is run together with Xamarin Studio or Visual Studio, the Java layer is run into its own dedicated process. To summarize what it does, let’s say that it mostly handles the heavy-lifting of parsing resources and rendering Android layouts.

That last duty specifically (rendering layouts) is actually accomplished by using an existing Google library called [layoutlib](https://android.googlesource.com/platform/tools/base/+/master/layoutlib-api/). It’s the same underlying library that powers the designer in Android Studio. Its goal is to take an XML layout, inflate it, layout it and render it to an image buffer.

Layoutlib is pretty nifty, it works by reusing an existing **android.jar** (which only contains the raw unimplemented Android API surface) and dynamically wires up enough implementation for classes and methods to be able to run a part of the Android experience on desktop. Key APIs are re-implemented using standard JRE libraries, a good example being the Android Canvas API that is translated to equivalent AWT calls for instance.

This process is done dynamically behind the scenes when you instantiate the library. It will automatically fetch the **android.jar** archive corresponding to the API level you want to use and plug it with the desktop implementation that is contained in another archive in the platform (aptly named **layoutlib.jar** ). If you are curious, you can also [view that code online](https://android.googlesource.com/platform/frameworks/base/+/master/tools/layoutlib/bridge/src/android/).

The end result is a Java `ClassLoader` instance that allow you to retrieve and instantiate all of the Android framework classes like `android.view.View`. This `ClassLoader` isolation is actually very handy because it allows to load several version of the platform at the same time (i.e. different `android.view.View` definitions) without polluting the main process class space.

In addition to this, layoutlib uses a system of callback to let consumers of the library provide additional input. One of such callback is invoked when layoutlib tries to inflate an item in a layout that it doesn’t know about because it doesn’t come from the framework `ClassLoader` I described above. As you probably guessed, those items are the custom user views.

### Tying in Custom Controls

Because [Xamarin.Android](https://github.com/xamarin/xamarin-android) lets you use both Java and .NET based components (the former being wrapped into bindings, including our [Android support libraries components](https://github.com/xamarin/AndroidSupportComponents)), it was essential to support both of them in the designer.

Java components are actually fairly easy since the rendering process is already running in a JVM. You simply have to reference the custom component `.jar` code (usually distributed as part of an Android library project in a `.aar` file) into something like a `URLClassLoader` instance and wire the loading in the layoutlib callback I mentioned.

The fun stuff is obviously to include the managed components. But before we dwelve into that too much, let’s make a quick recap on how Xamarin.Android works or, more precisely, how it integrates with the Java virtual machine it’s running on.

### Putting some C# in your Java

What I am going to describe here mostly relates to our legacy implementation in [Xamarin.Android](https://github.com/xamarin/xamarin-android) although much of the same ideas still live on in our new [Java.Interop library](https://github.com/xamarin/Java.Interop) (essentially in a cleaned up way).

The goal of Xamarin.Android _in fine_ is to allow managed code to be run inside an existing Java runtime and ensure both of them can talk to each other. To accomplish this, it embeds the Mono runtime inside the process and allows it to coexist with the existing Java VM.

To allow communication between the two worlds, it uses the concept of _bridged objects_. Everytime a Java object is surfaced to the managed world (e.g. a overriden method parameter) or when a managed (likely autogenerated) wrapper to a Java object is created, a peering process happens whereby the managed instance and the Java instance become linked to each other, sharing their lifetime (meaning one can’t be collected without the other) until the link is cut.

To call Java code from the managed world, the [JNI invocation API](http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp16656) is used. To let Java code call into the managed world (due to subclassing or callbacks), a Java wrapper class is automatically generated.

Those wrappers (called ACW/JCW for Android/Java Callable Wrappers) contain a bunch of `native` methods definition to act as thunks. The thunks are then dynamically plugged using the `RegisterNatives` [JNI call](http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp5833) with a function pointer into essentially a `mono_runtime_invoke` call.

For instance, take the following `MyCustomView` subclass written in C# like this with its `OnDraw` method overriden:

```
public class MyCustomView: Android.Views.View
{
	public override OnDraw (Canvas c)
	{}
}
```

During build, an equivalent Java file will be generated, compiled and packaged in your APK:

```
package md55d31ab91effba0f9ed7ec79c59c38391;

public class MyCustomView
       extends android.view.View
       implements mono.android.IGCUserPeer
{
        public void onDraw (android.graphics.Canvas p0)
        {
                n_onDraw (p0);
        }

        private native void n_onDraw (android.graphics.Canvas p0);
}
```

When you reference that custom view in your XML layout you will likely do it in this fashion:

```
<MyNamespace.MyCustomView
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent" />
```

With some extra Xamarin.Android processing, this will tell the Android layout inflater to load the Java class previously generated and, when trying to draw the view, will end up calling the managed implementation of the `OnDraw` method through its native thunk.

### Back to custom controls

Now that we have a clearer picture on how managed C# views are instantiated in an Android environment, it’s very easy to get them loaded into the designer. Simply add their generated ACW to the special `URLClassLoader` I mentioned beforehand and they will get processed like any other standard Java custom views.

Only thing left to do was to port our Xamarin.Android/Mono runtime to be able to run natively inside a standard Java desktop VM (in the same fashion than layoutlib with the Android API) so that it could execute the other side of that shim custom view. That code is also now open-source and you can [view it on GitHub](https://github.com/xamarin/xamarin-android/tree/master/src/monodroid/jni).

As part of this porting work some dusting off of our AppDomain implementation was required, especially to ensure it worked reliably in a “mobile” context. AppDomains are used as a natural complement to Java’s class loaders allowing the same silo’ed approach on both the Java and managed side.

Thanks to this association, the designer can create several context where multiple version of Android can be run together in an isolated fashion and refreshed binaries can be reloaded without the need for the renderer process itself to be torn down.

### Finishing up

![Android designer custom controls](https://blog.neteril.org/wp-content/uploads/android-designer-custom-controls/xs_custom_controls.png)

The layout rendered above extracted from [one of my demo project](https://github.com/garuma/Buzzeroid) contains a lot of different type of custom controls like AppBarLayout, Toolbar, RecyclerView, CoordinatorLayout and custom views for FloatingActionButton. By the way, the same feature is what’s also used in our Xamarin.Forms previewer to display the Android rendering of a layout.

There are more things that could be covered here, specifically I never mentioned how we handle error cases or even critical runtime failures which are bound to happen when you load external user code anywhere. Suffice to say we need some good error handling and process resurrection mechanisms which were definitely some of the hardest aspects to implement in the project (and still are).

Not all the code for what’s here is open-source but there are a quite few more things to look at if you are interested:

- Some (old but still relevant) [presentation of Xamarin.Android internals](https://vimeo.com/43529195) at NDC Oslo by [@shana](https://twitter.com/sh4na)
- The [Java.Interop repository](https://github.com/xamarin/Java.Interop) is a good look at how Xamarin.Android plumbing work (also has documention in eponymous folder).
- Xamarin developer portal has a lot of content 
  - [Working With JNI](https://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/working_with_jni/)
  - [Under The Hood guides](https://developer.xamarin.com/guides/android/under_the_hood/)
- The [Xamarin.Android open-source repository](https://github.com/xamarin/xamarin-android)