Skip to content

fix(core-render-android): snapshot text-post-processor result to avoid StaticLayout mutation crash - #1556

Open
yukiykchen wants to merge 2 commits into
Tencent-TDS:mainfrom
yuki-0721:richtext-crash
Open

fix(core-render-android): snapshot text-post-processor result to avoid StaticLayout mutation crash#1556
yukiykchen wants to merge 2 commits into
Tencent-TDS:mainfrom
yuki-0721:richtext-crash

Conversation

@yukiykchen

Copy link
Copy Markdown
Contributor

No description provided.

@KuiklyAI KuiklyAI left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 KuiklyAI Code Review

基本信息

  • PR:#1556 · fix(core-render-android): snapshot text-post-processor result to avoid StaticLayout mutation crash
  • 作者:yukiykchen main ← richtext-crash

变更概述

  • 干了什么:在 KRRichTextShadow.createLayout 中,对文本后置处理器(krTextPostProcessorAdapter.onTextPostProcess)返回的文本做一次不可变快照(复制为 SpannedString/String),再交给 StaticLayout 排版。
  • 解决什么:作者意图——避免业务侧持有的可变文本对象(如复用的 SpannableStringBuilder)在 StaticLayout 创建之后被异步修改/缩短,导致排版缓存的字符区间与真实文本长度失配,从而在测量或绘制时抛出 IndexOutOfBoundsException
  • 方案 & 合理性:方向正确,且层级合适——在渲染层入口处切断业务对象与 Layout 之间的引用关系,比依赖业务方保证不可变更稳妥。非后置处理器路径下 textSource 是框架每次 buildLayout 临时新建、立即消费、不复用不修改的 SpannableStringBuilder,因此只快照后置处理器结果、不动常规路径是合理的,没有扩大改动面。

审查结论

整体改动正确、范围收敛,没有发现功能性问题。两点轻微的代码质量建议(见 inline):① snapshotLayoutText 里的 is Spannable 分支是不可达死代码;② 顺带改动了一处无关的缩进(isNougatLineBreakMarginCompat)。都不影响行为,按需清理即可。文档侧无公共 API / 组件 / 平台行为变化,无需同步文档。

@KuiklyAI KuiklyAI left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 KuiklyAI Code Review

基本信息

  • PR:#1556 · fix(core-render-android): snapshot text-post-processor result to avoid StaticLayout mutation crash
  • 作者:yukiykchen main ← richtext-crash

变更概述

  • 干了什么:在后置文本处理器(TextPostProcessorOutput.text)返回的文本交给 StaticLayout 排版前,新增 snapshotLayoutText() 做一次不可变快照(拷贝为 SpannedString/不可变对象),切断业务侧持有的可变 CharSequence 与 Layout 之间的引用。
  • 解决什么:业务侧复用可变对象(如 SpannableStringBuilder)并在 Layout 创建后异步修改时,StaticLayout 缓存的排版区间与真实文本长度不一致,导致测量/绘制阶段抛 IndexOutOfBoundsException
  • 方案 & 合理性:方向正确,命中在 Android 渲染层、排版入口前这一最合适的层级,从设计上规避误用,方案合理。原始 text 参数来自框架内部 buildSimpleText()/buildRichText() 每次重新构造、measure 调用内即用即弃,无需快照,本次聚焦后置处理器返回的业务对象是对准的。

整体评价

修复点抓得准,注释也写得很清楚,整体可以合入。有一处 when 分支顺序带来的死代码/可读性小问题,见下方 inline 评论。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants