24

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);
    }
}
emmby
  • 99,783
  • 65
  • 191
  • 249
Tony Wong
  • 5,444
  • 5
  • 22
  • 18

6 Answers6

9

This is a known bug, that will be fixed in ICS MR1.

Gilles Debunne
  • 309
  • 1
  • 4
7

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

yhpark
  • 175
  • 1
  • 2
  • 9
5

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?

Community
  • 1
  • 1
Marten
  • 3,802
  • 1
  • 17
  • 26
0

I'm experiencing the same. My Gingerbread devices all work fine, but testing on my Galaxy Nexus this situation arises predictably. What your experiencing is likely why the MR1 and 4.0.3 updates rolled out so quickly.

Noah Seidman
  • 4,359
  • 5
  • 26
  • 28
-2

I got the same problem, I solved it by hiding the EditText ondismiss of my dialog.

  mEditText.setVisibility(View.GONE);
otiasj
  • 59
  • 6
-2

You are running into the situation described in the Android resources section on memory leaks. See that page for some solutions as well.

Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68
  • I feel like I'm already correctly following the guidelines set out in that article. I do not keep static references to the Context. I do not use non-static inner classes. Finally, I avoided using the Application Context instead of the Activity Context because View instance lifetime is the same as the Activity's. Furthermore, if I had used an XML layout instead of adding the EditView programmatically, I wouldn't be able to use the Application Context anyways. – Tony Wong Dec 14 '11 at 00:26