为什么EditText在冰淇淋三明治中保留其活动的上下文

在Ice Cream Sandwich中,当有一个包含EditText的Activity时,EditText即使在用户离开Activity后也会保留Activity的Context。 为了演示这一点,我创建了TestLeakActivity,它分配一个大的字节数组。 由于Activity的上下文从不被垃圾收集,字节数组堆积在堆上,最终导致OutOfMemoryError。 您可以通过使用DDMS堆工具观察堆增长,并且可以通过查看Eclipse MAT中的HPROF文件来跟踪对EditText类的未完成引用。 要创建内存泄漏,请进入LaunchActivity并保持启动并退出TestLeakActivity。

LaunchActivity.java
package com.example.testleakproject;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class LaunchActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Button button = new Button(this);
        button.setText("Start TestLeakActivity");
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(LaunchActivity.this, TestLeakActivity.class);
                startActivity(intent);
            }
        });

        ViewGroup container = ((ViewGroup) findViewById(android.R.id.content));
        container.addView(button);
    }
}
TestLeakActivity.java
package com.example.testleakproject;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.EditText;

public class TestLeakActivity extends Activity {
    private byte[] mSomeBytes = new byte[1048576];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        EditText editText = new EditText(this);
        editText.setHint("TestLeakActivity");

        ViewGroup container = ((ViewGroup) findViewById(android.R.id.content));
        container.addView(editText);
    }
}

这是一个已知的错误,将在ICS MR1中修复。


直到现在,这个问题还没有解决。 (Android 4.2.1)


我花了几个小时才发现我受到这个问题的影响。

这个问题似乎是由拼写检查器造成的。 当我禁用EditText视图的建议时,所有内容都可以正确垃圾收集。

mInputType = mText.getInputType();
mText.setInputType(mInputType | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

我不想禁用它,因为许多用户需要拼写检查。 因此,也许有一种方法可以在输入字段接收焦点时暂时启用它。

如果您不需要拼写检查器,只需将它添加到布局xml中的EditText元素即可:

android:inputType="textNoSuggestions"

这似乎也解决了这个问题。

编辑:

刚刚发现此线程似乎是相关的:解决SpellCheckerSession泄漏?

链接地址: http://www.djcxy.com/p/26233.html

上一篇: Why does EditText retain its Activity's Context in Ice Cream Sandwich

下一篇: bufferedReader for URL throws IOException