Search code examples
androidxamarin.androidxamarin.forms

[MissingMethodException: No constructor found for Xamarin.Forms.Maps.Android.MapRenderer::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)]


I have implemented a Google Map in my Xamarin forms app but am getting the above exception when navigating away from the page before the map has completed loading the current location.

This is probably the same issue previously raised but unanswered here.

From my research I believe the issue is related to leaky abstration answer given in this separate question: MonoDroid: Error when calling constructor of custom view - TwoDScrollView

However I do not have enough knowledge of Java or Android development to know how to resolve this issue. I am hoping that someone can explain where and how I can handle this exception when it occurs. Basically what I believe I need to achieve is catching the exception and handle it in the Droid project, but where?

These are the key exception messages that I am getting.

Message: [NotSupportedException: Unable to activate instance of type Xamarin.Forms.Maps.Android.MapRenderer from native handle 0xbef7ad5c (key_handle 0xd4608e7).]

Message: [MissingMethodException: No constructor found for Xamarin.Forms.Maps.Android.MapRenderer::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)]

Message: [Exception of type 'Java.Interop.JavaLocationException' was thrown.]


Solution

  • However I do not have enough knowledge of Java or Android development to know how to resolve this issue. I am hoping that someone can explain where and how I can handle this exception when it occurs.

    I think the reason is when you are navigating the pages, the Dispose method of Xamarin.Forms.Maps.Android.MapRenderer is called before the loading of the rest of the map. ACW need to create a new instance of MapRenderer but failed to create a new one because MapRenderer has no constructor method of (IntPtr, JniHandleOwnership).

    If you refer to Premature Dispose() Calls you can find following statement:

    If the subclass does contain an (IntPtr, JniHandleOwnership) constructor, then a new instance of the type will be created.

    So the workaround for this exception is to create a subclass(Let's say MyMapRenderer) for Xamarin.Forms.Maps.Android.MapRenderer,which has a constructor with two arguments: (IntPtr, JniHandleOwnership), and use MyMapRenderer for map rendering:

    1. In PCL create a custom control for Xamarin.Forms.Map.Map and use MyMap instead in your project:

      public class MyMap:Map{}
      
    2. Create a Custom MapRenderer in Droid project,which has a (IntPtr, JniHandleOwnership) contructor:

      [assembly:ExportRenderer(typeof(MyMap),typeof(MyMapRenderer))]
      namespace YourNameSpace.Droid
      {
          public class MyMapRenderer:MapRenderer
          {
              public MyMapRenderer(IntPtr handle, JniHandleOwnership transfer) { }
          }
      }
      

    For details about create a custom MapRenderer, please refer to Custom a Map.