Tony Wong
Tony Wong

Reputation: 5454

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);
    }
}

Upvotes: 24

Views: 3431

Answers (6)

otiasj
otiasj

Reputation: 59

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

  mEditText.setVisibility(View.GONE);

Upvotes: -2

Marten
Marten

Reputation: 3862

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?

Upvotes: 5

yhpark
yhpark

Reputation: 175

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

Upvotes: 7

Noah Seidman
Noah Seidman

Reputation: 4409

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.

Upvotes: 0

Gilles Debunne
Gilles Debunne

Reputation: 309

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

Upvotes: 9

Cody Caughlan
Cody Caughlan

Reputation: 32748

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

Upvotes: -2

Related Questions