Android动态添加视图设置Tag时出现forEach循环异常求助
问题分析与解答
针对你遇到的三个疑问,我们逐一拆解背后的原因:
1. 为什么forEach循环仅执行两次?
最可能的原因是循环处理第三个视图时遭遇了未被捕获的运行时异常,导致循环提前终止。Android主线程的Looper会自动捕获未处理的异常避免崩溃,但会中断当前的循环执行。可能的异常场景包括:
- 低版本Android系统(API < 17)中,
View.generateViewId()存在生成重复ID的bug,导致设置ID时触发异常; viewToBeCreated?.eventMapFragmentRootConstraintLayout在第三次迭代时意外变为null,调用addView(it)触发空指针异常;- 设置
tag时,confirmInterfaceTag的类型或状态不符合要求(比如是已被回收的弱引用对象),触发异常。
这些异常被系统捕获后,循环会在第三次迭代中途中断,因此你观察到循环仅执行了两次。
2. 循环仅执行两次,为何三个视图都被添加?
这是因为第三个视图的addView(it)调用在异常发生前已经执行完成。在forEach的闭包中,代码执行顺序是:
it.id = View.generateViewId() it.tag = confirmInterfaceTag it.alpha = 0f viewToBeCreated?.eventMapFragmentRootConstraintLayout?.addView(it) // 这行先执行完成 it.animate().alpha(1f).duration = confirmInterfaceFadeInFadeOutAnimation
如果异常发生在it.tag = confirmInterfaceTag或后续步骤,addView(it)已经成功执行,视图会被添加到布局中,但后续代码未完成。此时循环虽然终止,但三个视图都已被添加(前两个完整执行,第三个执行到addView后中断)。
3. 三个视图都被添加的情况下,为何其中一个ImageView缺失Tag?
原因和上面一致:该ImageView的it.tag = confirmInterfaceTag代码在异常发生前未执行,或执行时触发异常导致设置失败。比如:
- 如果异常发生在
it.id = View.generateViewId()之后、it.tag = confirmInterfaceTag之前,tag根本没被设置; - 如果异常发生在设置tag的语句中,tag设置会失败,最终视图的tag保持默认的
null。
而动画正常生效,是因为animate()的调用在异常发生前已经完成,或者异常发生在动画设置之后(此时动画已经启动)。
为什么修改后的代码能解决问题?
你修改后的代码将confirmLocationTickImage单独用apply处理,把三个视图的逻辑拆分到了两个独立执行块中。这样即使其中一个块出现异常,也不会影响另一个块的执行,保证所有视图都能完整完成tag设置、布局添加和动画启动的流程。
内容的提问来源于stack exchange,提问作者Metin
相关产品推荐
相关产品推荐

