Why does EditText retain its Activity's Context in Ice Cream Sandwich

In Ice Cream Sandwich, when there's an Activity containing an EditText, the EditText will retain the Activity's Context even after the user leaves the Activity. To demonstrate this I've created TestLeakActivity, which allocates a large byte array. Since the Activity's Context is never garbage collected, the byte arrays accumulate on the heap, eventually causing an OutOfMemoryError. You can observe the heap growth by using the DDMS heap tool, and you can track the outstanding references to the EditText class by looking at the HPROF file in Eclipse MAT. To create memory leaks, go into LaunchActivity and just keep launching and backing out of 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中修复。


This has not been fixed until now. (Android 4.2.1)


I've just spend several hours to find that I'm affected by this issue.

The issue seems to be caused by the spell checker. When I disable suggestions for the EditText view everything is properly garbage collected.

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

I don't really want to disable this, since many users want spell checking. So, maybe there is a way to temporarily enable it when the input field receives the focus.

If you don't need the spell checker just add this to the EditText element in your layout xml instead:

android:inputType="textNoSuggestions"

That seems to fix it too.

Edit:

Just found this thread that appears to be related: Work around SpellCheckerSession leak?

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

上一篇: 删除所有本地文件并从git下载新的副本

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