Xamarin.Forms应用启动崩溃:System.ObjectDisposedException异常求助
问题描述
每次启动Xamarin.Forms应用都会抛出异常并崩溃,重启应用无法恢复,仅能通过卸载重装解决。重装后无需修改代码即可正常运行,但异常一旦出现就必须重装才能恢复。
异常日志
7-29 22:34:26.291 4590 4590 I MonoDroid: UNHANDLED EXCEPTION:
07-29 22:34:26.295 4590 4590 I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception of type 'Android.Runtime.JavaProxyThrowable' was thrown.
07-29 22:34:26.296 4590 4590 I MonoDroid: --- End of managed Android.Runtime.JavaProxyThrowable stack trace ---
07-29 22:34:26.296 4590 4590 I MonoDroid: android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
07-29 22:34:26.296 4590 4590 I MonoDroid: Object name: 'Xamarin.Forms.Platform.Android.ShellFlyoutRenderer'.
07-29 22:34:26.296 4590 4590 I MonoDroid: at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in :0
07-29 22:34:26.296 4590 4590 I MonoDroid: at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualBooleanMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in :0
07-29 22:34:26.296 4590 4590 I MonoDroid: at Android.Views.View.Post (Java.Lang.IRunnable action) [0x00036] in <1db5751744294c2d9a12968f7500aa0a>:0
07-29 22:34:26.296 4590 4590 I MonoDroid: at Android.Views.View.Post (System.Action action) [0x00008] in <1db5751744294c2d9a12968f7500aa0a>:0
07-29 22:34:26.296 4590 4590 I MonoDroid: at Xam.Shell.Badge.Droid.Renderers.BadgeShellItemRenderer.b__7_0 () [0x0000b] in <03ed10528a1e495baf36a579de381653>:0
07-29 22:34:26.296 4590 4590 I MonoDroid: at Xamarin.Forms.Device+<>c__DisplayClass42_0`1[T].b__0 () [0x00000] in <62e3629c74b84e3d834046331d2bb5f8>:0
07-29 22:34:26.296 4590 4590 I MonoDroid: --- End of stack trace from previous location where exception was thrown ---
环境信息
- Xamarin.Forms版本:5.0.0.2401
- 目标操作系统:Android 8.1
- 开发工具:Visual Studio 2022 专业版
问题分析与解决步骤
从日志能明确,问题源于Xam.Shell.Badge库的BadgeShellItemRenderer组件,它尝试在已被释放的ShellFlyoutRenderer对象上调用View.Post方法,触发了ObjectDisposedException。
具体解决方法
升级
Xam.Shell.Badge库
该库大概率存在内存引用管理的bug,直接升级到最新稳定版,多数情况下官方已修复此类对象释放后仍被调用的问题。自定义渲染器修复
如果无法升级库,可自定义渲染器覆盖原有逻辑,在执行Post操作前先检查对象是否存活:
[assembly: ExportRenderer(typeof(ShellItem), typeof(FixedBadgeShellItemRenderer))] namespace YourApp.Droid.Renderers { public class FixedBadgeShellItemRenderer : BadgeShellItemRenderer { protected override void UpdateBadge() { // 替换原有Post逻辑,添加对象存活检查 if (!IsDisposed && View != null && !View.IsDisposed) { View.Post(() => base.UpdateBadge()); } } } }
清理应用持久化状态
卸载重装本质是清除了应用的缓存和持久化数据,可在应用启动时主动清理相关目录(如SharedPreferences、缓存文件夹),避免旧状态导致的无效对象引用。升级Xamarin.Forms版本
当前使用的5.0.0.2401存在不少已知的Shell渲染器内存管理问题,升级到5.x系列的最新版本(如5.0.0.2515),能修复底层的对象生命周期管理bug。
内容的提问来源于stack exchange,提问作者Nishant Sharma

