Since applications on Android require generating Java proxy types during the build process, it is not possible to generate all code at runtime.
These are the Xamarin.Android limitations compared to desktop mono:
Limited Dynamic Language Support
Android callable wrappers are needed any time the Android runtime needs to invoke managed code. Android callable wrappers are generated at compile time by the mandroid.exe tool, based on static analysis of IL. The net result of this: you cannot use dynamic languages (IronPython, IronRuby, etc.) in any scenario where subclassing of Java types is required (including indirect subclassing), as there's no way of extracting these dynamic types at compile time to generate the necessary Android callable wrappers.
Limited Java Generation Support
Android Callable Wrappers need to be generated in order for Java code to call managed code. By default, Android callable wrappers will only contain (certain) declared constructors and methods which override a virtual Java method (i.e. it has [Register]) or implement a Java interface method (interface likewise has [Register]).
Prior to the 4.1 release, no additional methods could be declared. With the 4.1 release, the [Export] and [ExportField] custom attributes can be used to declare Java methods and fields within the Android Callable Wrapper.
Constructors remain tricky, unless [Export] is used. The algorithm for generating Android callable wrapper constructors is that a Java constructor will be emitted if (1) there is a Java mapping for all the parameter types, and (2) the base class declares the same constructor. (2) is required because the Android callable wrapper must invoke the corresponding base class constructor; no default arguments can be used (as there's no easy way to determine what values should be used within Java).
For example, consider the following class:
[Service] class MyIntentService : IntentService { public MyIntentService () : base ("value") { } }
While this looks perfectly logical, the resulting Android callable wrapper in Release builds will not contain a default constructor. Consequently, if you attempt to start this service (e.g. Context.StartService(new Intent (context, typeof(MyIntentService)))), it will fail:
E/AndroidRuntime(31766): FATAL EXCEPTION: main E/AndroidRuntime(31766): java.lang.RuntimeException: Unable to instantiate service example.MyIntentService: java.lang.InstantiationException: can't instantiate class example.MyIntentService; no empty constructor E/AndroidRuntime(31766): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2347) E/AndroidRuntime(31766): at android.app.ActivityThread.access$1600(ActivityThread.java:130) E/AndroidRuntime(31766): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277) E/AndroidRuntime(31766): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(31766): at android.os.Looper.loop(Looper.java:137) E/AndroidRuntime(31766): at android.app.ActivityThread.main(ActivityThread.java:4745) E/AndroidRuntime(31766): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(31766): at java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime(31766): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) E/AndroidRuntime(31766): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) E/AndroidRuntime(31766): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime(31766): Caused by: java.lang.InstantiationException: can't instantiate class example.MyIntentService; no empty constructor E/AndroidRuntime(31766): at java.lang.Class.newInstanceImpl(Native Method) E/AndroidRuntime(31766): at java.lang.Class.newInstance(Class.java:1319) E/AndroidRuntime(31766): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2344) E/AndroidRuntime(31766): ... 10 more
This is due to a linker bug.
The workaround is to not use the IntentService(string) constructor and instead use the default constructor:
[Service] class MyIntentService : IntentService { [Obsolete ("DO NOT USE", true)] public MyIntentService () { } // ... }
Android.OS.IParcelable cannot be implemented.
This limitation applies to prior versions to 4.1 release. In 4.1 release,
you can use ExportAttribute and ExportField attribute to generate Java methods
and fields that can be named explicitly.
The IParcelable interface cannot be implemented at this time because
the android.os.Parcelable interface requires:
Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
Since mandroid.exe currently cannot generate fields, this interface cannot be implemented. Support will be added in a future release.
Java.IO.ISerializable cannot be implemented.
This limitation applies to prior versions to 4.1 release. In 4.1 release,
you can use ExportAttribute and ExportField attribute to generate Java methods
and fields that can be named explicitly.
The ISerializable interface cannot currently be implemented because the
java.io.Serializable interface requires that the
implementing class provide readObject() and writeObject()
methods. Since mandroid.exe currently cannot generate user-specified methods,
this interface cannot be implemented.
Use of Third Party Java Libraries
This limitation applies to prior versions to 4.1 release. In 4.1 release,
you can use a
Java binding library project.
Third party .jar files
cannot currently be easily used and extended from managed code. Some JNI support is
provided, but subclassing and implementing third party classes and
interfaces isn't possible via Android.Runtime.JNIEnv.
Partial Java Generics Support
The Java generics binding support is limited. Particularly, members in a generic instance class that is derived from another generic (non-instantiated) class are left exposed as Java.Lang.Object. For example, Android.Content.Intent.GetParcelableExtra method returns Java.Lang.Object. This is due to erased Java generics. We have some classes that do not apply this limitation, but they are manually adjusted.