fra*_*ish 5 android listview memory-leaks textview linkmovementmethod
我有一个ListView和它adapter的getView方法,我返回一个RelativeLayout与MyButton它里面。
MyButton有一个textView,我在里面有可点击的词 ( ClickableSpan)。
为了完成这项工作,我从以下行开始:
textView.setMovementMethod(LinkMovementMethod.getInstance());
一切正常,但 MAT 显示MyButton泄漏是因为textView. 当我注释掉上面的行时,没有任何泄漏。
我应当设置movementMethod到null?但即使是这样,我也不知道按钮的破坏时刻将其设置null为在许多其他视图中。
我究竟做错了什么?如何防止这种泄漏?

更新
通过将 text 设置为里面的空字符串解决了泄漏问题onDetachedFromWindow,但我仍在尝试查找与此行为相关的文档。为什么要设置textview为""?
小智 5
我面临的另一个内存泄漏TextView,ClickableSpan以及LinkMovementMethod同时里面做的超链接Fragment。第一次点击设备的超链接和旋转后,由于NPE无法再次点击。
为了弄清楚发生了什么,我进行了调查,这是结果。
TextView在进入静态内部类的实例期间mText,保存包含字段的副本。它仅在特定条件下发生。在我的例子中,它是可点击部分的 a ,它是在第一次点击跨度后设置的。ClickableSpanonSaveInstanceState()SavedStateSelectionLinkMovementMethod
接下来,如果存在已保存的状态,则从期间TextView对字段 进行恢复mText,包括所有跨度。TextView.SavedState.textonRestoreInstanceState()
这是一个有趣的部分。什么时候onRestoreInstanceState()叫?它在 之后调用onStart()。我设置了一个新对象ClickableSpaninonCreateView()但在onStart()旧对象替换新对象后,这导致了大问题。
因此,解决方案非常简单但没有记录 -ClickableSpan在onStart().
您可以在我的博客TextView、ClickableSpan 和内存泄漏上阅读完整调查,并使用示例项目。
您的问题很可能是由 引起的NoCopySpan。onSaveInstanceState()在 KitKat 之前,TextView 会使用 SpannableString制作 Span 的副本并将其放置在 Bundle 中。由于某种原因,SpannableString 不会删除 NoCopySpans,因此保存的状态保存对原始 TextView 的引用。此问题已在后续版本中修复。
将文本设置为“”可以解决该问题,因为包含 NoCopySpan 的原始文本已正确 GC。
LeakCanary建议的解决方法是......
黑客:要解决此问题,您可以重写 TextView.onSaveInstanceState(),然后使用反射来访问 TextView.SavedState.mText 并清除 NoCopySpan 跨度。
可以在此处找到LeakCanary 针对此泄漏的排除条目。
| 归档时间: |
|
| 查看次数: |
2224 次 |
| 最近记录: |