Closed sonnguyen0310 closed 5 years ago
I'm not sure what is reason for it.
But we released "how to cache images" with v3.0.0 .
Please try implement your CachingNativeBitmapDescriptorFactory .
@amay077 Thank for your quick reply. I will try to implement it and report here if it happens again.
@amay077 CachingNativeBitmapDescriptorFactory look cannot resolve the problem, I will continuous investigate it and report the root cause later
I got the same issue but its not easy to reproduce. Sometime the app crashs when rendering custom pin from view.
Look like I fixed this bug, that I do not see crash log anymore for couple weeks.
In my case, this happen because of synchronized thread running at the same time, for an example, call add pin while the map is clearing the pins.
So i make it await, try to handle it not called to add, clear pins at the same time and it good to go.
Hi @sonnguyen0310 , Good report!
I suggest your use only UI thread for create and add, remove or clear pins.
This means do not use async/await
or Task<T>
for it.
@langtu , please check your using threads.
Hi,
It seems that the issue still exists although I put all code of add/remove/clear pins within Device.BeginInvokeOnMainThread()
.
Here's my crash log:
LinkedList`1[T].InternalRemoveNode (System.Collections.Generic.LinkedListNode`1[T] node)
System.NullReferenceException: Object reference not set to an instance of an object
LinkedList`1[T].InternalRemoveNode (System.Collections.Generic.LinkedListNode`1[T] node)
LinkedList`1[T].RemoveFirst ()
Utils+<>c__DisplayClass6_0.<ConvertViewToBitmapDescriptor>b__0 ()
Task`1[TResult].InnerInvoke ()
Task.Execute ()
ExceptionDispatchInfo.Throw ()
TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task)
TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task)
TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task)
TaskAwaiter`1[TResult].GetResult ()
PinLogic+<TransformXamarinViewToAndroidBitmap>d__31.MoveNext ()
ExceptionDispatchInfo.Throw ()
AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state)
SyncContext+<>c__DisplayClass2_0.<Post>b__0 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) System.Object.26dfa028-9e84-49d0-82ab-149862c32528(intptr,intptr)
I temporary fix the issue by rebuild code using lock
in method ConvertViewToBitmapDescriptor
in class Xamarin.Forms.GoogleMaps.Android.Utils
(https://github.com/amay077/Xamarin.Forms.GoogleMaps/blob/v3.0.1/Xamarin.Forms.GoogleMaps/Xamarin.Forms.GoogleMaps.Android/Utils.cs):
return Task.Run(() => {
var bmp = ConvertViewToBitmap(v);
var img = global::Android.Gms.Maps.Model.BitmapDescriptorFactory.FromBitmap(bmp);
var buffer = ByteBuffer.Allocate(bmp.ByteCount);
bmp.CopyPixelsToBuffer(buffer);
buffer.Rewind();
// https://forums.xamarin.com/discussion/5950/how-to-convert-from-bitmap-to-byte-without-bitmap-compress
IntPtr classHandle = JNIEnv.FindClass("java/nio/ByteBuffer");
IntPtr methodId = JNIEnv.GetMethodID(classHandle, "array", "()[B");
IntPtr resultHandle = JNIEnv.CallObjectMethod(buffer.Handle, methodId);
byte[] bytes = JNIEnv.GetArray<byte>(resultHandle);
JNIEnv.DeleteLocalRef(resultHandle);
var sha = MD5.Create();
var hash = Convert.ToBase64String(sha.ComputeHash(bytes));
var exists = cache.ContainsKey(hash);
lock (lruTracker)
{
if (exists)
{
lruTracker.Remove(hash);
lruTracker.AddLast(hash);
return cache[hash];
}
if (lruTracker.Count > 10) // O(1)
{
global::Android.Gms.Maps.Model.BitmapDescriptor tmp;
cache.TryRemove(lruTracker.First.Value, out tmp);
lruTracker.RemoveFirst();
}
lruTracker.AddLast(hash);
}
cache.GetOrAdd(hash, img);
return img;
});
@amay077
I also don't understand why this method need lruTracker
and cache
fields although the img
always be created. Why do not immediately return img
without check for caching?
@langtu I think it's because LinkedList is not a thread-safe implementation. Ref: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.linkedlist-1.system-collections-icollection-syncroot?view=netframework-4.8
I believe your fix is legit. @amay077 can you please include this to master and make a release to nuget?
Could you send Pull request?
Hi guys,
I have the same issue in v3.2.1 in Android platform, I also added the PlatformConfig like @amay077 said in the advice above, even though, when I use CachingNativeBitmapDescriptorFactory the render view for custom pin crashed, I'm running my application in Motorola 2g and 3g Android 6 (Marshmellow) and 8 (Oreo), the detail about stack trace is below:
Source: mscorlib
Message: Object reference not set to an instance of an object.
at Xamarin.Forms.GoogleMaps.Android.Utils+<>cDisplayClass2_0.
at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in
at System.Threading.Tasks.Task.Execute () [0x00000] in
at Xamarin.Forms.GoogleMaps.Logics.Android.PinLogic.TransformXamarinViewToAndroidBitmap(Xamarin.Forms.GoogleMaps.Pin outerItem, Android.Gms.Maps.Model.Marker nativeItem)
[0x0013b] in <15e1414cdc6345fe95968791274ef90d>:0 \n
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.
at Android.App.SyncContext+<>c
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) 0x00009] in
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.46(intptr,intptr)
I hope this helps.
Thanks in advance.
Same
at Xamarin.Forms.GoogleMaps.Android.Utils+<>c__DisplayClass2_0.
at Xamarin.Forms.GoogleMaps.Logics.Android.PinLogic.TransformXamarinViewToAndroidBitmap (Xamarin.Forms.GoogleMaps.Pin outerItem, Android.Gms.Maps.Model.Marker nativeItem) [0x0013b] in
Hi all i have solved the issue, error occurred on below method which is found in Xamarin.Forms.GoogleMaps.Android.Util.cs classs.
public static Task
in the line "var viewGroup = vRenderer.ViewGroup;" it is giving a warning "ViewGroup is obsolete as of version 2.3.5. Please use View instead.".on the runtime , its getting null. so i have fixed it by implementing the suggestion that is given in the warning, here is the fix
public static Task
i am new in github don't know how to commit this code.
Hi, this is still happening in version 3.3.0, Xamarin.Forms 4.5.0:
at System.Collections.Concurrent.ConcurrentDictionary2[TKey,TValue].ThrowKeyNotFoundException (System.Object key) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs:912 at System.Collections.Concurrent.ConcurrentDictionary
2[TKey,TValue].get_Item (TKey key) [0x0000b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs:893
at Xamarin.Forms.GoogleMaps.Android.Utils+<>cDisplayClass6_0.
@amay077 can you implement fix suggested above?
Anyone still experiences this like me?
ConcurrentDictionary
2[TKey,TValue].ThrowKeyNotFoundException (System.Object key)
ConcurrentDictionary2[TKey,TValue].get_Item (TKey key) Utils+<>c__DisplayClass6_0.<ConvertViewToBitmapDescriptor>b__0 () Task
1[TResult].InnerInvoke ()
Task.Execute ()
PinLogic.TransformXamarinViewToAndroidBitmap (Xamarin.Forms.GoogleMaps.Pin outerItem, Android.Gms.Maps.Model.Marker nativeItem)
AsyncMethodBuilderCore+<>c.
Anyone still experiences this like me?
ConcurrentDictionary
2[TKey,TValue].ThrowKeyNotFoundException (System.Object key) ConcurrentDictionary2[TKey,TValue].get_Item (TKey key) Utils+<>c__DisplayClass6_0.<ConvertViewToBitmapDescriptor>b__0 () Task
1[TResult].InnerInvoke () Task.Execute () PinLogic.TransformXamarinViewToAndroidBitmap (Xamarin.Forms.GoogleMaps.Pin outerItem, Android.Gms.Maps.Model.Marker nativeItem) AsyncMethodBuilderCore+<>c.b7_0 (System.Object state) SyncContext+<>c__DisplayClass2_0.b0 () Thread+RunnableImplementor.Run () IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.5(intptr,intptr)`
Same here
VERSIONS
PLATFORMS
ACTUAL BEHAVIOR
Android 7.0 When I using custom Pin view with the local resource, sometimes it make a crash.
ACTUAL SCREENSHOTS/STACKTRACE
EXPECTED BEHAVIOR
Is anyway to fix it ?
HOW TO REPRODUCE
It's not 100% reproduce, just happen randomly when I try to add multi-marker by using for loop as the code below