You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms Android端非托管代码抛出ConcurrentModificationException异常求解

异常诱因
  • 从堆栈信息可以明确异常触发在Telerik RadScrollView的notifyLaidOutListeners方法中:该方法遍历监听器集合时,集合被其他线程同时修改,触发了ArrayList的并发修改校验。
  • 常见触发场景包括:后台线程直接修改RadScrollView的绑定数据源、子元素属性、滚动状态等,刚好和UI线程的布局遍历操作撞在同一时间点;使用的Telerik UI for Xamarin版本过旧,旧版本的RadScrollView未对监听器遍历做并发保护;RadScrollView与Xamarin原生ScrollView嵌套使用,反复触发布局事件导致监听器集合被频繁修改。
解决方案
  • 优先升级Telerik UI for Xamarin到2022 Q2及以上的稳定版本,该版本官方已经修复了这个并发问题,修复逻辑为遍历监听器前先生成集合副本,避免原集合修改影响遍历过程。
  • 所有涉及RadScrollView的属性修改、子元素增删、数据源更新操作,全部用Device.BeginInvokeOnMainThread包裹,强制在UI线程执行,杜绝跨线程修改集合的可能。
  • 若暂时无法升级Telerik版本,可在Android平台自定义RadScrollView的Renderer,捕获该偶发异常即可,不会影响正常布局逻辑,示例代码如下:
[assembly: ExportRenderer(typeof(Telerik.XamarinForms.Primitives.RadScrollView), typeof(CustomRadScrollViewRenderer))]
namespace 你的应用命名空间.Droid.Renderers
{
    public class CustomRadScrollViewRenderer : Telerik.XamarinForms.Primitives.Renderer.Android.ScrollView.RadScrollViewRenderer
    {
        public CustomRadScrollViewRenderer(Context context) : base(context) { }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            try
            {
                base.OnLayout(changed, left, top, right, bottom);
            }
            catch (Java.Util.ConcurrentModificationException)
            {
                // 忽略该偶发异常
            }
        }
    }
}
  • 检查页面布局结构,避免RadScrollView与原生ScrollView嵌套使用,统一用RadScrollView作为滚动容器,减少不必要的布局事件触发。

内容的提问来源于stack exchange,提问作者Kikanye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:24:02