在Xamarin中,如何处理“读取越界”图像异常,这种异常似乎只在软键盘被移除时发生?

u91tlkcl  于 2023-08-01  发布在  其他
关注(0)|答案(1)|浏览(98)

每当软键盘因任何原因从视图中移除时,我在GalaxyS22+上的Xamarin.Forms应用程序中遇到以下异常。

System.BadImageFormatException: Read out of bounds.
   at System.Reflection.Throw.OutOfBounds()
   at System.Reflection.Metadata.Ecma335.MethodDebugInformationTableReader.GetDocument(MethodDebugInformationHandle handle)
   at Mono.Debugging.Soft.PortablePdbData.GetDebugInfoFromPdb(MethodMirror method) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging.Soft\PortablePdbData.cs:line 186
   at Mono.Debugging.Soft.SoftDebuggerBacktrace.CreateStackFrame(StackFrame frame, Int32 frameIndex) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging.Soft\SoftDebuggerBacktrace.cs:line 157
   at Mono.Debugging.Soft.SoftDebuggerBacktrace.GetStackFrames(Int32 firstIndex, Int32 lastIndex) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging.Soft\SoftDebuggerBacktrace.cs:line 128
   at Mono.Debugging.Client.Backtrace.GetFrame(Int32 index, Int32 fetchMultipleCount) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging\Mono.Debugging.Client\Backtrace.cs:line 61
   at Mono.Debugging.Client.Backtrace..ctor(IBacktrace serverBacktrace) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging\Mono.Debugging.Client\Backtrace.cs:line 27
   at Mono.Debugging.Soft.SoftDebuggerSession.HandleBreakEventSet(Event[] es, Boolean dequeuing) in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging.Soft\SoftDebuggerSession.cs:line 2186
   at Mono.Debugging.Soft.SoftDebuggerSession.EventHandler() in D:\a\_work\1\s\External\debugger-libs\Mono.Debugging.Soft\SoftDebuggerSession.cs:line 1802

字符串
我使用的IDE是Visual Studio Community 2022,Xamarin.Forms版本是5.0.0.2244,我的Android版本更新到当前版本。
我从来没有遇到过这样的问题,堆栈跟踪对我来说没有意义。我试过切换到Release模式,因为看起来问题似乎发生在调试器中,但应用程序仍然在同一点崩溃。我检查了我们在应用中心的崩溃报告,它看起来与我从VS获得的堆栈跟踪完全不同。以下是该报告的开头:

Package: myApp
Version Code: 19
Version Name: 0.18
Android: 13
Android Build: TP1A.220624.014
Manufacturer: samsung
Model: SM-S906U
CrashReporter Key: 29ac0cda-bcdc-4ead-a7f5-bd7a6d812874
Start Date: 2023-07-13T14:11:12.247Z
Date: 2023-07-13T14:11:54.391Z

Xamarin Exception Stack:
Java.Lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
  at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <3c553ea2ef344db484f0fd0644ad8207>:0
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00076] in <3c553ea2ef344db484f0fd0644ad8207>:0
  at Android.Views.ViewGroup.AddView (Android.Views.View child) [0x00031] in <8c63cbc465e14a70ade7127aa5abe07e>:0
  at Xamarin.Forms.Platform.Android.SwipeViewRenderer.UpdateContent () [0x0004c] in <b0894a26774f4d8c9615005666aba8aa>:0
  at Xamarin.Forms.Platform.Android.SwipeViewRenderer.OnElementChanged (Xamarin.Forms.Platform.Android.ElementChangedEventArgs`1[TElement] e) [0x00060] in <b0894a26774f4d8c9615005666aba8aa>:0
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000d3] in <b0894a26774f4d8c9615005666aba8aa>:0
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00033] in <b0894a26774f4d8c9615005666aba8aa>:0
  at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element, Android.Content.Context context) [0x0003e] in <b0894a26774f4d8c9615005666aba8aa>:0


这个问题并不是我的设备独有的,因为我在同事的Android平板电脑上重现了同样的问题。还没有机会在iOS上运行该应用程序,所以我不确定这是否是Android OS独有的,但如果这里没有足够的信息,我可以在那里报告我的发现。
我试过在部署之前对解决方案进行清理和重建,删除项目的obj和bin文件夹(这在过去已经解决了VS的几个问题),尝试不同的设备,并重新启动VS。例外没有任何变化。
我曾尝试在应用程序中使用不同的文本字段进行测试,但仍存在相同的问题。下拉式输入的工作,因为他们不拉上软键盘。

4uqofj5v

4uqofj5v1#

所以我认为我们找到了解决方案,但这不是软键盘的问题。
Xamarin的实现MVVM基础架构层通过当前堆栈中的每个视图页面向下传播所有更改事件。在我们的主视图中,它是整个应用程序的基础,并且总是在堆栈中,有一个ListView没有指定的CachingStrategy,并且由于某种原因,无法使用默认策略。
当软键盘关闭时,很可能是通过堆栈中的每个视图传播已更改的事件,并且由于这个ListView无法回收其现有视图之一,因此它试图在不首先删除父视图的情况下创建一个新视图,我假设父视图是某种只允许单个非嵌套子视图的元素。
这是我最好的猜测,因为一旦我们将CachingStrategy="RecycleElement"添加到主页列表的属性中,问题就解决了。

相关问题