Issue: https://code.google.com/p/android/issues/detail?id=59310
android.text.TextLine has memory leak on mSpanned and SpanSet.
使用下面的工具类移除泄漏:
public class TextLineRecycler {
private static Field sCached;
private static Field sCharacterStyleSpanSet;
private static Field sMetricAffectingSpanSpanSet;
private static Field sReplacementSpanSpanSet;
private static Field sSpans;
private static Field sSpanned;
private static Field sText;
static {
try {
Class clazz = Class.forName("android.text.TextLine");
sCached = clazz.getDeclaredField("sCached");
sSpanned = clazz.getDeclaredField("mSpanned");
sText = clazz.getDeclaredField("mText");
sCached.setAccessible(true);
sSpanned.setAccessible(true);
sText.setAccessible(true);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
sCharacterStyleSpanSet = clazz.getDeclaredField("mCharacterStyleSpanSet");
sMetricAffectingSpanSpanSet = clazz.getDeclaredField("mMetricAffectingSpanSpanSet");
sReplacementSpanSpanSet = clazz.getDeclaredField("mReplacementSpanSpanSet");
Class spanSetClass = Class.forName("android.text.SpanSet");
sSpans = spanSetClass.getDeclaredField("spans");
sCharacterStyleSpanSet.setAccessible(true);
sMetricAffectingSpanSpanSet.setAccessible(true);
sReplacementSpanSpanSet.setAccessible(true);
sSpans.setAccessible(true);
}
} catch (Exception e) {
Log.e("TextLineRecycler", "", e);
}
}
/**
* recycle system TextLine
*/
public static void recycle() {
try {
Object cached = sCached.get(null);
int length = Array.getLength(cached);
if (cached != null) {
synchronized (cached) {
for (int i = 0; i < length; i++) {
Object textLine = Array.get(cached, i);
if (textLine != null) {
Object text = sText.get(textLine);
// mText has been recycled, recycle mSpanned and other SpanSet here
if (null == text && null != sSpanned.get(textLine)) {
sSpanned.set(textLine, null);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
recycleSpan(sCharacterStyleSpanSet, textLine);
recycleSpan(sMetricAffectingSpanSpanSet, textLine);
recycleSpan(sReplacementSpanSpanSet, textLine);
}
}
}
}
}
}
} catch (Exception e) {
Log.e("TextLineRecycler", "", e);
}
}
private static <T extends CharacterStyle> void recycleSpan(Field field, Object textLine)
throws IllegalArgumentException, IllegalAccessException {
Object spanSet = field.get(textLine);
T[] spans = (T[]) TextLineRecycler.sSpans.get(spanSet);
if (spans != null) {
for (int i = 0; i < spans.length; i++) {
spans[i] = null;
}
}
}
}
分享到:
相关推荐
双缓存机制下,Android应用会对大内存的图片做二级缓存,对于溢出缓存的bitmap实行recycle,但是有些bitmap正在显示,会造成概率性的花屏等, 该方案提供了一套完整的防止recycle正在显示的bitmap的方案
二、Android(Java)中常见的容易引起内存泄漏的不良代码 1 (一) 查询数据库没有关闭游标 2 (二) 构造Adapter时,没有使用缓存的 convertView 3 (三) Bitmap对象不在使用时调用recycle()释放内存 4 (四) 释放对象的...
人教版三年级下册英语教案:Recycle 1 Recycle 1 第3课时.doc
Recycle1教学课件1.ppt
新人教PEP版四年级下册小学英语 Recycle 1 教学反思.docx
新人教PEP版四年级下册小学英语 Recycle 2 教学反思.docx
recycle.bin是什么-.docx
recycle误删文件恢复 recycle误删文件恢复 recycle误删文件恢复
小学英语六年级上册Recycle1教案.pdf
ListView列表中使用 Recycle
Recycle1课件.ppt
实现一种回收机制LPCTSTR pszPathName = GetFileNameSomehow(); // 通过某函数获得文件的全路径名!...rf.Recycle(pszPathName); //将文件放到Recycle Bin中 //rf.Recycle(pszPathName, true); //将文件直接删除
四年级英语下册Recycle 1练习题精选.doc
六年级英语下册Recycle测试题及答案含听力【人教版】精选.doc
(人教PEP)三年级英语上册教案 Recycle 2(11)
三年级英语上册recycle1第三课时.ppt
pep六年级下册Recycle课时练习题及答案3.doc
pep六年级下册Recycle课时练习题及答案.doc
pep六年级下册Recycle课时练习题及答案2.doc
六年级下册Recycle教案.pdf