Cross Platform
Android
iOS
Mac
 

Troubleshooting

Offline Activation

If you're unable to activate Xamarin.Android on Windows, or unable to install the full version of Xamarin.Android on Mac OS X, please see the Offline Activation page.

Android Debug Logs

The Android Debug Logs may provide additional context regarding any runtime errors you're seeing.

Floating-Point performance is terrible!

Alternatively, "My app runs 10x faster with the Debug build than with the Release build!"

Xamarin.Android supports multiple device ABIs: armeabi, armeabi-v7a, and x86. Device ABIs can be specified within Project Properties > Application tab > Supported architectures.

Debug builds use an Android package which provides all ABIs, and thus will use the fastest ABI for the target device.

Release builds will only include the ABIs selected in the Project Properties tab. More than once can be selected.

armeabi is the default ABI, and has the broadest device support. However, armeabi doesn't support multi-CPU devices and hardware floating-point, amont other things. Consequently, apps using the armeabi Release runtime will be tied to a single core and will be using a soft-float implementation. Both of these can contribute to significantly slower performance for your app.

If your app requires decent floating-point performance (e.g. games), you should enable the armeabi-v7a ABI. You may want to only support the armeabi-v7a runtime, though this means that older devices which only support armeabi will be unable to run your app.

Could not locate Android SDK

There are 2 downloads available from Google for the Android SDK for Windows. If you choose the .exe installer, it will write registry keys that tell Xamarin.Android where it was installed. If you choose the .zip file and unzip it yourself, Xamarin.Android does not know where to look for the SDK. You can tell Xamarin.Android where the SDK is in Visual Studio by going to Tools -> Options -> Xamarin -> Android Settings, or in Xamarin Studio by going to Xamarin Studio -> Preferences -> SDK Locations:

IDE does not display target device

Sometimes you will attempt to deploy your application to a device, but the device you want to deploy to isn't shown in the Select Device dialog. This can happen when the Android Debug Bridge decides to go on vacation.

To diagnose this issue, find the adb program, then run:

adb devices

If your device isn't present, then you need to restart the Android Debug Bridge server so that your device can be found:

adb kill-server
adb start-server

HTC Sync software may prevent `adb start-server` from working properly. If the `adb start-server` command doesn't print out which port it's starting on, please exit the HTC Sync software and try restarting the adb server.

The specified task executable "keytool" could not be run

This means that your PATH does not contain the directory where the Java SDK's bin directory is located. Check that you followed those steps from the Installation guide.

monodroid.exe or aresgen.exe exited with code 1

To help you debug this problem, go into Visual Studio and change the MSBuild verbosity level, to do this, select: Tools->Options->Project and Solutions->Build and Run->MSBuild Project Build Output Verbosity and set this value to Normal.

Rebuild, and check Visual Studio's Output pane, which should contain the full error.

There is not enough storage space on the device to deploy the package

This occurs when you don't start the emulator from within Visual Studio. When starting the emulator outside of Visual Studio, you need to pass the -partition-size 512 options, e.g.

emulator -partition-size 512 -avd MonoDroid

Ensure you use the correct simulator name, i.e. the name you used when configuring the simulator.

INSTALL_FAILED_INVALID_APK when installing a package

Android package names must contain a period ('.'). Edit your package name so that it contains a period.

  • Within Visual Studio:
    • Right click your project > Properties
    • Click the Android Manifest tab on the left.
    • Update the Package name field.
      • If you see the message "No AndroidManifest.xml found. Click to add one.", click the link and then update the Package name field.
  • Within Xamarin Studio:
    • Right click your project > Options.
    • Navigate to the Build / Android Application section.
    • Change the Package name field to contain a '.'.

INSTALL_FAILED_MISSING_SHARED_LIBRARY when installing a package

A "shared library" in this context is not a native shared library (libfoo.so) file; it is instead a library that must be separately installed on the target device, such as Google Maps.

The Android package specifies which shared libraries are required with the <uses-library/> element. If a required library is not present on the target device (e.g. //uses-library/@android:required is true, which is the default), then package installation will fail with INSTALL_FAILED_MISSING_SHARED_LIBRARY.

To determine which shared libraries are required, view the generated AndroidManifest.xml file (e.g. obj\Debug\android\AndroidManifest.xml) and look for the <uses-library/> elements. <uses-library/> elements can be added manually in your project's Properties\AndroidManifest.xml file and via the UsesLibraryAttribute custom attribute.

For example, adding an assembly reference to Mono.Android.GoogleMaps.dll will implicitly add a <uses-library/> for the Google Maps shared library.

INSTALL_FAILED_UPDATE_INCOMPATIBLE when installing a package

Android packages have three requirements:

  • They must contain a '.' (see previous entry)
  • They must have a unique string package name (hence the reverse-tld convention seen in Android app names, e.g. com.android.chrome for the Chrome app)
  • When upgrading packages, the package must have the same signing key.

Thus, imagine this scenario:

  1. You build & deploy your app as a Debug app
  2. You change the signing key, e.g. to use as a Release app (or because you don't like the default-provided Debug signing key)
  3. You install your app without removing it first, e.g. Debug > Start Without Debugging within Visual Studio

When this happens, package installation will fail with a INSTALL_FAILED_UPDATE_INCOMPATIBLE error, because the package name didn't change while the signing key did. The Android Debug Log will also contain a message similar to:

E/PackageManager(  146): Package [PackageName] signatures do not match the previously installed version; ignoring!

To fix this error, completely remove the application from your device before re-installing.

Release apps fail to launch on device

Does the Android Debug Log output will contain a message similar to:

D/AndroidRuntime( 1710): Shutting down VM
W/dalvikvm( 1710): threadid=1: thread exiting with uncaught exception (group=0xb412f180)
E/AndroidRuntime( 1710): FATAL EXCEPTION: main
E/AndroidRuntime( 1710): java.lang.UnsatisfiedLinkError: Couldn't load monodroid: findLibrary returned null
E/AndroidRuntime( 1710):        at java.lang.Runtime.loadLibrary(Runtime.java:365)

If so, there are two possible causes for this:

  1. The .apk doesn't provide an ABI that the target device supports. For example, the .apk only contains armeabi-v7a binaries, and the target device only supports armeabi.
  2. An Android bug. If this is the case, uninstall the app, cross your fingers, and reinstall the app.

To fix (1), edit the Project Options/Properties and add support for the required ABI to the list of Supported ABIs. To determine which ABI you need to add, run the following adb command against your target device:

adb shell getprop ro.product.cpu.abi
adb shell getprop ro.product.cpu.abi2

The output will contain the primary (and optional secondary) ABIs.

$ adb shell getprop | grep ro.product.cpu
[ro.product.cpu.abi2]: [armeabi]
[ro.product.cpu.abi]: [armeabi-v7a]

The OutPath property is not set for project "MyApp.csproj"

This generally means you have an HP computer and the environment variable "Platform" has been set to something like MCD or HPD. This conflicts with the MSBuild Platform property that is generally set to "Any CPU" or "x86".



You will need to remove this environment variable from your machine before MSBuild can function:

  • Control Panel > System > Advanced > Environment Variables

Restart Visual Studio or Xamarin Studio and try to rebuild. Things should now work as expected.

java.lang.ClassCastException: mono.android.runtime.JavaObject cannot be cast to...

Xamarin.Android 4.x doesn't properly marshal nested generic types properly. For example, consider the following C# code using SimpleExpandableListAdapter:

// BAD CODE; DO NOT USE
var groupData = new List<IDictionary<string, object>> () {
        new Dictionary<string, object> {
                { "NAME", "Group 1" },
                { "IS_EVEN", "This group is odd" },
        },
};
var childData = new List<IList<IDictionary<string, object>>> () {
        new List<IDictionary<string, object>> {
                new Dictionary<string, object> {
                        { "NAME", "Child 1" },
                        { "IS_EVEN", "This group is odd" },
                },
        },
};
mAdapter = new SimpleExpandableListAdapter (
        this,
        groupData,
        Android.Resource.Layout.SimpleExpandableListItem1,
        new string[] { "NAME", "IS_EVEN" },
        new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 },
        childData,
        Android.Resource.Layout.SimpleExpandableListItem2,
        new string[] { "NAME", "IS_EVEN" },
        new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 }
);

The problem is that Xamarin.Android incorrectly marshals nested generic types. The List&lt;IDictionary&lt;string, object&gt;&gt; is being marshaled to a java.lang.ArrrayList, but the ArrayList is containing mono.android.runtime.JavaObject instances (which reference the Dictionary&lt;string, object&gt; instances) instead of something that implements java.util.Map, resulting in the following exception:

E/AndroidRuntime( 2991): FATAL EXCEPTION: main
E/AndroidRuntime( 2991): java.lang.ClassCastException: mono.android.runtime.JavaObject cannot be cast to java.util.Map
E/AndroidRuntime( 2991):        at android.widget.SimpleExpandableListAdapter.getGroupView(SimpleExpandableListAdapter.java:278)
E/AndroidRuntime( 2991):        at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:446)
E/AndroidRuntime( 2991):        at android.widget.AbsListView.obtainView(AbsListView.java:2271)
E/AndroidRuntime( 2991):        at android.widget.ListView.makeAndAddView(ListView.java:1769)
E/AndroidRuntime( 2991):        at android.widget.ListView.fillDown(ListView.java:672)
E/AndroidRuntime( 2991):        at android.widget.ListView.fillFromTop(ListView.java:733)
E/AndroidRuntime( 2991):        at android.widget.ListView.layoutChildren(ListView.java:1622)

The workaround is to use the provided Java Collection types instead of the System.Collections.Generic types for the "inner" types. This will result in appropriate Java types when marshaling the instances. (The following code is more complicated than necessary in order to reduce gref lifetimes. It can be simplified to altering the original code via s/List/JavaList/g and s/Dictionary/JavaDictionary/g if gref lifetimes aren't a worry.)

// insert good code here
using (var groupData = new JavaList<IDictionary<string, object>> ()) {
        using (var groupEntry = new JavaDictionary<string, object> ()) {
                groupEntry.Add ("NAME", "Group 1");
                groupEntry.Add ("IS_EVEN", "This group is odd");
                groupData.Add (groupEntry);
        }
        using (var childData = new JavaList<IList<IDictionary<string, object>>> ()) {
                using (var childEntry = new JavaList<IDictionary<string, object>> ())
                using (var childEntryDict = new JavaDictionary<string, object> ()) {
                        childEntryDict.Add ("NAME", "Child 1");
                        childEntryDict.Add ("IS_EVEN", "This child is odd.");
                        childEntry.Add (childEntryDict);
                        childData.Add (childEntry);
                }
                mAdapter = new SimpleExpandableListAdapter (
                        this,
                        groupData,
                        Android.Resource.Layout.SimpleExpandableListItem1,
                        new string[] { "NAME", "IS_EVEN" },
                        new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 },
                        childData,
                        Android.Resource.Layout.SimpleExpandableListItem2,
                        new string[] { "NAME", "IS_EVEN" },
                        new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 }
                );
        }
}

This will be fixed in a future release.

Unexpected NullReferenceExceptions

Occasionally the Android Debug Log will mention NullReferenceExceptions that "cannot happen," or come from Mono for Android runtime code shortly before the app dies:

E/mono(15202): Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
E/mono(15202):   at Java.Lang.Object.GetObject (IntPtr handle, System.Type type, Boolean owned)
E/mono(15202):   at Java.Lang.Object._GetObject[IOnTouchListener] (IntPtr handle, Boolean owned)
E/mono(15202):   at Java.Lang.Object.GetObject[IOnTouchListener] (IntPtr handle, Boolean owned)
E/mono(15202):   at Android.Views.View+IOnTouchListenerAdapter.n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_(IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e)
E/mono(15202):   at (wrapper dynamic-method) object:b039cbb0-15e9-4f47-87ce-442060701362 (intptr,intptr,intptr,intptr)

or

E/mono    ( 4176): Unhandled Exception:
E/mono    ( 4176): System.NullReferenceException: Object reference not set to an instance of an object
E/mono    ( 4176): at Android.Runtime.JNIEnv.NewString (string)
E/mono    ( 4176): at Android.Util.Log.Info (string,string)

This can happen when Dalvik decides to abort the process, which can happen for any number of reasons, including hitting the target's GREF limit or doing something "wrong" with JNI.

To see if this is the case, check the Android Debug Log for a message from your process similar to:

E/dalvikvm(  123): VM aborting

Abort due to Global Reference Exhaustion

Dalvik's JNI layer only supports a limited number of JNI object references to be valid at any given point in time. When this limit is exceeded, things break.

The GREF (global reference) limit is 2000 references in the emulator, and ~52000 references on hardware.

You know you're starting to create too many GREFs when you see messages such as this in the Android Debug Log:

D/dalvikvm(  602): GREF has increased to 1801

When you reach the GREF limit, a message such as the following is printed:

D/dalvikvm(  602): GREF has increased to 2001
W/dalvikvm(  602): Last 10 entries in JNI global reference table:
W/dalvikvm(  602):  1991: 0x4057eff8 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  1992: 0x4057f010 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm(  602):  1993: 0x40698e70 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  1994: 0x40698e88 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  1995: 0x40698ea0 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm(  602):  1996: 0x406981f0 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  1997: 0x40698208 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  1998: 0x40698220 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm(  602):  1999: 0x406956a8 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602):  2000: 0x406956c0 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm(  602): JNI global reference table summary (2001 entries):
W/dalvikvm(  602):    51 of Ljava/lang/Class; 164B (41 unique)
W/dalvikvm(  602):    46 of Ljava/lang/Class; 188B (17 unique)
W/dalvikvm(  602):     6 of Ljava/lang/Class; 212B (6 unique)
W/dalvikvm(  602):    11 of Ljava/lang/Class; 236B (7 unique)
W/dalvikvm(  602):     3 of Ljava/lang/Class; 260B (3 unique)
W/dalvikvm(  602):     4 of Ljava/lang/Class; 284B (2 unique)
W/dalvikvm(  602):     8 of Ljava/lang/Class; 308B (6 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 316B
W/dalvikvm(  602):     4 of Ljava/lang/Class; 332B (3 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 356B
W/dalvikvm(  602):     2 of Ljava/lang/Class; 380B (1 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 428B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 452B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 476B
W/dalvikvm(  602):     2 of Ljava/lang/Class; 500B (1 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 548B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 572B
W/dalvikvm(  602):     2 of Ljava/lang/Class; 596B (2 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 692B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 956B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 1004B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 1148B
W/dalvikvm(  602):     2 of Ljava/lang/Class; 1172B (1 unique)
W/dalvikvm(  602):     1 of Ljava/lang/Class; 1316B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 3428B
W/dalvikvm(  602):     1 of Ljava/lang/Class; 3452B
W/dalvikvm(  602):     1 of Ljava/lang/String; 28B
W/dalvikvm(  602):     2 of Ldalvik/system/VMRuntime; 12B (1 unique)
W/dalvikvm(  602):    10 of Ljava/lang/ref/WeakReference; 28B (10 unique)
W/dalvikvm(  602):     1 of Ldalvik/system/PathClassLoader; 44B
W/dalvikvm(  602):  1553 of Landroid/graphics/Point; 20B (1553 unique)
W/dalvikvm(  602):   261 of Landroid/graphics/Point; 28B (261 unique)
W/dalvikvm(  602):     1 of Landroid/view/MotionEvent; 100B
W/dalvikvm(  602):     1 of Landroid/app/ActivityThread$ApplicationThread; 28B
W/dalvikvm(  602):     1 of Landroid/content/ContentProvider$Transport; 28B
W/dalvikvm(  602):     1 of Landroid/view/Surface$CompatibleCanvas; 44B
W/dalvikvm(  602):     1 of Landroid/view/inputmethod/InputMethodManager$ControlledInputConnectionWrapper; 36B
W/dalvikvm(  602):     1 of Landroid/view/ViewRoot$1; 12B
W/dalvikvm(  602):     1 of Landroid/view/ViewRoot$W; 28B
W/dalvikvm(  602):     1 of Landroid/view/inputmethod/InputMethodManager$1; 28B
W/dalvikvm(  602):     1 of Landroid/view/accessibility/AccessibilityManager$1; 28B
W/dalvikvm(  602):     1 of Landroid/widget/LinearLayout$LayoutParams; 44B
W/dalvikvm(  602):     1 of Landroid/widget/LinearLayout; 332B
W/dalvikvm(  602):     2 of Lorg/apache/harmony/xnet/provider/jsse/TrustManagerImpl; 28B (1 unique)
W/dalvikvm(  602):     1 of Landroid/view/SurfaceView$MyWindow; 36B
W/dalvikvm(  602):     1 of Ltouchtest/RenderThread; 92B
W/dalvikvm(  602):     1 of Landroid/view/SurfaceView$3; 12B
W/dalvikvm(  602):     1 of Ltouchtest/DrawingView; 412B
W/dalvikvm(  602):     1 of Ltouchtest/Activity1; 180B
W/dalvikvm(  602): Memory held directly by tracked refs is 75624 bytes
E/dalvikvm(  602): Excessive JNI global references (2001)
E/dalvikvm(  602): VM aborting

In the above example (which, incidentally, comes from bug 685215) the problem is that too many Android.Graphics.Point instances are being created; see comment #2 for a list of fixes for this particular bug.

Typically, a useful solution is to find which type has too many instances allocated -- Android.Graphics.Point in the above dump -- then find where they're created in your source code and dispose of them appropriately (so that their Java-object lifetime is shortened). This is not always appropriate (#685215 is multithreaded, so the trivial solution avoids the Dispose call), but it's the first thing to consider.

You can enable GREF Logging to see when GREFs are created and how many exist.

Abort due to JNI type mismatch

If you hand-roll JNI code, it's possible that the types won't match correctly, e.g. if you try to invoke java.lang.Runnable.run on a type that doesn't implement java.lang.Runnable. When this occurs, there will be a message similar to this in the Android Debug Log:

W/dalvikvm( 123): JNI WARNING: can't call Ljava/Type;;.method on instance of Lanother/java/Type;
W/dalvikvm( 123):              in Lmono/java/lang/RunnableImplementor;.n_run:()V (CallVoidMethodA)
...
E/dalvikvm( 123): VM aborting

Dynamic Code Support

Dynamic code does not compile

To use C# dynamic in your application or library, you have to add System.Core.dll, Microsoft.CSharp.dll and Mono.CSharp.dll to your project.

In Release build, MissingMethodException occurs for dynamic code at run time.

  • It is likely that your application project does not have references to System.Core.dll, Microsoft.CSharp.dll or Mono.CSharp.dll. Make sure those assemblies are referenced.
    • Keep in mind that dynamic code always costs. If you need efficient code, consider not using dynamic code.
  • In the first preview, those assemblies were excluded unless types in each assembly are explicitly used by the application code. See the following for a workaround: http://lists.ximian.com/pipermail/mo...il/009798.html