IOS端Dialog dispose行为异常,二次及以上实例化后应用卡死问题求助
问题基础信息
运行环境
- 操作系统:Windows 10 专业版
- IDE:NetBeans 12.2
- 测试环境:最新版Codename One模拟器、Android端、iOS端
异常表现
仅iOS端出现异常:同一Form实例下,Dialog第二次及以上实例化时触发应用卡死,模拟器和Android端运行完全符合预期。
复现步骤
- 在Form内点击按钮实例化Dialog类型类
A1MMASiteMeterReadDialog,传入若干Vector类型数据并执行相关任务,实例化代码为:a1SiteMeterReadDialog = new A1MMASiteMeterReadDialog(a1MMAHomePage, res, inc); - 任务完成后调用
dispose()销毁该Dialog实例 - 用户可多次触发操作打开该Dialog,iOS端第二次及以上打开时出现不稳定表现:部分TextField运行异常、无法响应ActionListener,后续操作几步后应用直接卡死
- 异常发生时Codename One日志和iOS原生日志均无异常输出,未捕捉到抛出的异常信息,仅能强制停止应用后重启
初步根因猜测
- iOS端
dispose()方法的执行逻辑与Android、模拟器存在差异,未正常完成实例销毁 - iOS端持有该Dialog类的首个实例引用,重新实例化时未完成完全清理,进而导致不稳定现象
排查解决建议
- 改用Dialog实例复用逻辑:取消每次打开新建实例的逻辑,全局仅初始化一次
A1MMASiteMeterReadDialog实例,每次打开前手动重置内部数据、TextField状态、监听器绑定,关闭时仅调用dispose()隐藏不销毁实例,验证是否还会出现卡死。如果复用后问题消失,可明确问题出在实例销毁/重建环节的iOS端适配差异。 - 校验UI操作线程合法性:确保所有
dispose()调用、Dialog实例化、UI组件操作都在*事件调度线程(EDT)*中执行,iOS端对非EDT线程操作UI的容错率极低,非EDT线程操作UI销毁极易出现无日志的死锁问题,可将dispose()相关代码包裹在CN.callSerially()中验证。 - 清理Dialog内部引用:检查
A1MMASiteMeterReadDialog类中是否持有外部Form、大体积资源、静态变量的强引用,静态强引用会导致实例无法被GC回收,多次创建后引发内存泄漏在iOS端触发卡死,如有相关引用改为实例引用或使用弱引用包裹。 - 禁用Dialog过渡动画:iOS端部分自定义过渡动画在Dialog频繁销毁重建时可能出现渲染层死锁,可在Dialog初始化后调用
setTransitionInAnimator(null)、setTransitionOutAnimator(null)禁用过渡动画,复现操作排查是否为动画渲染引发的卡死。 - 手动清理组件监听器:如果Dialog内部的TextField绑定了ActionListener、数据校验监听器,在调用
dispose()前手动移除所有绑定的监听器,清空TextField内容后再执行销毁操作,排除监听器多次绑定引发的事件冲突。
内容的提问来源于stack exchange,提问作者Mark Bolduc
相关产品推荐
相关产品推荐

