为什么EditText在Ice Cream Sandwich中保留其Activity的Context

时间:2011-12-13 23:57:34

标签: android memory-leaks android-4.0-ice-cream-sandwich

在Ice Cream Sandwich中,当有一个包含EditText的Activity时,即使用户离开Activity,EditText也会保留Activity的Context。为了证明这一点,我创建了TestLeakActivity,它分配了一个大字节数组。由于Activity的Context不会被垃圾收集,因此字节数组会在堆上累积,最终导致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);
    }
}

6 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:7)

直到现在还没有修复。 (Android 4.2.1)

答案 2 :(得分:4)

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

这个问题似乎是由拼写检查引起的。当我禁用EditText视图的建议时,一切都被正确地垃圾收集。

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

我真的不想禁用它,因为很多用户都想要拼写检查。因此,当输入字段获得焦点时,可能有一种临时启用它的方法。

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

android:inputType="textNoSuggestions"

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

修改

刚刚发现这个似乎相关的帖子:Work around SpellCheckerSession leak?

答案 3 :(得分:0)

我也遇到了同样的问题。我的姜饼设备都运行良好,但在我的Galaxy Nexus上测试这种情况可以预见。您的体验可能是为什么MR1和4.0.3更新如此迅速地推出。

答案 4 :(得分:-2)

您正遇到Android resources section on memory leaks中描述的情况。有关一些解决方案,请参阅该页面。

答案 5 :(得分:-2)

我遇到了同样的问题, 我通过隐藏EditText ondismiss对话来解决它。

  mEditText.setVisibility(View.GONE);