I am using TouchTracking.Forms with Prism.Forms INavigationService for app on Andriod platform.
OnTouchAction is used for navigation between view by INavigationService. For example in touchReleasedactionHandler call:
navigationService.NavigateAsync($"/{nameof(someView)}");
If I frequantly switching between pages by touching corresponded buttons with attached OnTouchAction then generated exception:
{System.ArgumentException: An item with the same key has already been added. Key: 0
at System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) [0x000dd] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:531
at System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:240
at **TouchTracking.Droid.TouchHandler.OnTouch** (System.Object sender, Android.Views.View+TouchEventArgs args) [0x0008f] in <16086595d2354bd2a5fae8bf7e121c37>:0
at Android.Views.View+IOnTouchListenerImplementor.OnTouch (Android.Views.View v, Android.Views.MotionEvent e) [0x00014] in /Users/builder/azdo/_work/30/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Android.Views.View.cs:4028
at Android.Views.View+IOnTouchListenerInvoker.n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_v, System.IntPtr native_e) [0x00018] in /Users/builder/azdo/_work/30/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Android.Views.View.cs:3967
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.53(intptr,intptr,intptr,intptr)}
The exception is thrown when trying to add a duplicate key 1 or 0 to dictionary the TouchHandler._idToTouchHandlerDictionary.
I found that there might be a case where an element receives a touch action (adding touch to _idToTouchHandlerDictionary) and does not receive a touch release action (remove touch from _idToTouchHandlerDictionary) because it was previously disposed.
During disposing, the visual element is detahed from the "TouchEffect" effect. "TouchEffect" calls "_touchHandler.UnregisterEvents (_view)" where happens unscribing from "view.Touch" event:
view.Touch -= OnTouch;
Is it need to add some code that will be removed elements associated with disposed or detached view? It solves problem in my case.
public override void UnregisterEvents(View view)
{
try
{
view.GetHashCode();
}
catch (ObjectDisposedException) //view can be already disposed and we have no other way to remove it from dictionary
{
Console.WriteLine($"___disposed view:{Type.GetTypeHandle(view).Value}");
var newDictionary = new Dictionary<View, TouchHandler>();
foreach (KeyValuePair<View, TouchHandler> item in _viewDictionary)
{
try
{
newDictionary[item.Key] = item.Value;
}
catch (ObjectDisposedException)
{
continue;
}
}
_viewDictionary = newDictionary;
return;
}
if (_viewDictionary.ContainsKey(view))
{
_viewDictionary.Remove(view);
// Is it need to add this processing?
var idToTouchHandlerDictKeys = _idToTouchHandlerDictionary
.Where(x => x.Value._view == view)
.Select(x => x.Key)
.Distinct();
foreach (var key in idToTouchHandlerDictKeys)
{
_idToTouchHandlerDictionary.Remove(key);
}
//---
view.Touch -= OnTouch;
Console.WriteLine($"___OnTouch removed view:{Type.GetTypeHandle(view).Value}");
}
}
I am using TouchTracking.Forms with Prism.Forms INavigationService for app on Andriod platform.
OnTouchAction is used for navigation between view by INavigationService. For example in touchReleasedactionHandler call: navigationService.NavigateAsync($"/{nameof(someView)}");
If I frequantly switching between pages by touching corresponded buttons with attached OnTouchAction then generated exception:
The exception is thrown when trying to add a duplicate key 1 or 0 to dictionary the TouchHandler._idToTouchHandlerDictionary.
I found that there might be a case where an element receives a touch action (adding touch to _idToTouchHandlerDictionary) and does not receive a touch release action (remove touch from _idToTouchHandlerDictionary) because it was previously disposed.
During disposing, the visual element is detahed from the "TouchEffect" effect. "TouchEffect" calls "_touchHandler.UnregisterEvents (_view)" where happens unscribing from "view.Touch" event:
view.Touch -= OnTouch;
Is it need to add some code that will be removed elements associated with disposed or detached view? It solves problem in my case.
in TouchHandler.UnregisterEvents