Issue
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 href="https://stackoverflow.com/questions/38403650/xamarin-android-google-maps-exception-when-closing-page-with-map/42252932?noredirect=1#comment71664627_42252932">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:
In PCL create a custom control for
Xamarin.Forms.Map.Map
and useMyMap
instead in your project:public class MyMap:Map{}
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.
Answered By - Elvis Xia - MSFT
Answer Checked By - Katrina (JavaFixing Volunteer)