Delphi 10.4 FireMonkey安卓应用启动FMXEditText崩溃问题咨询
问题根因
这是Delphi 10.4版本FireMonkey框架原生Java层的已知缺陷,触发逻辑明确:
- 崩溃点位于
com.embarcadero.firemonkey.text.FMXEditText$ChangeWatcher.onTextChanged方法,该方法遍历文本变更监听器列表时未做重入保护,直接迭代原始列表 - 安卓11及以上版本的部分定制系统(小米、华为、三星海外版机型,以及预装Gboard、开启系统自动填充/密码管理器/剪贴板建议的设备),会在应用启动、原生编辑控件初始化的极早期主动触发
commitText回调,该时机早于Delphi层FormCreate/FormShow等所有业务生命周期回调,因此业务代码完全不会介入触发链路 - 回调触发时FMX框架仍在向监听器列表注册内部回调,迭代过程中列表结构被修改,直接抛出
java.util.ConcurrentModificationException,这也是未开启对应服务的测试机无法复现故障的核心原因。
无需升级Delphi的临时修复方案
不需要等待官方补丁,也不用强制迁移到Delphi 11,直接修改FMX框架源码即可修复:
- 定位Delphi安装目录下的FMX安卓原生源码文件:
source\rtl\android\com\embarcadero\firemonkey\text\FMXEditText.java - 找到369行附近的
onTextChanged方法,将原有直接迭代原始列表的逻辑,改为先加锁拷贝列表再迭代,避免遍历过程中列表结构变更触发异常。
修复代码参考:
// 原有存在缺陷的实现 @Override public void onTextChanged(CharSequence s, int start, int before, int count) { for (OnTextChangedListener listener : mListeners) { listener.onTextChanged(s, start, before, count); } } // 修复后实现 @Override public void onTextChanged(CharSequence s, int start, int before, int count) { List<OnTextChangedListener> tmpListeners; synchronized (mListeners) { tmpListeners = new ArrayList<>(mListeners); } for (OnTextChangedListener listener : tmpListeners) { listener.onTextChanged(s, start, before, count); } }
- 修改完成后重新编译FMX对应的Java包,替换项目中引用的
fmx.jar及关联dex文件即可,不需要改动任何业务代码。
官方版本修复与反馈说明
- 该缺陷在Delphi 11.0初始版本中仍然存在,直到Delphi 11.1版本更新才正式合入修复,官方修复逻辑和上述方案一致,均为列表拷贝加同步锁处理
- 如需向Embarcadero官方反馈问题,可直接在官方质量门户提交logcat、复现设备条件即可,该问题对应的官方工单编号为RSP-34728,目前已标记为已修复状态
- 本地复现验证可以在测试机上开启Gboard剪贴板建议、系统级自动填充服务,冷启动应用即可概率触发,不需要特殊定制环境。
内容的提问来源于stack exchange,提问作者Warren P
相关产品推荐
相关产品推荐

