Почему EditText сохраняет контекст своей активности в Ice Cream Sandwich

В Ice Cream Sandwich, когда есть действие, содержащее EditText, EditText сохранит контекст действия даже после того, как пользователь покинет действие. Чтобы продемонстрировать это, я создал TestLeakActivity, который выделяет большой массив байтов. Поскольку контекст действия никогда не собирает мусор, байтовые массивы накапливаются в куче, в конечном итоге вызывая OutOfMemoryError. Вы можете наблюдать за ростом кучи с помощью инструмента DDMS heap, а также отслеживать выдающиеся ссылки на класс EditText, просматривая файл HPROF в Eclipse MAT. Чтобы создать утечку памяти, войдите в 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);
    }
}

person Tony Wong    schedule 13.12.2011    source источник


Ответы (6)


Это известная ошибка, которая будет исправлена ​​в ICS MR1.

person Gilles Debunne    schedule 14.12.2011
comment
Я все еще наблюдаю похожую (если не идентичную) утечку в Android L. - person emmby; 23.09.2014
comment
Возможно, этот обходной путь может вам помочь: stackoverflow.com/a/27231817/1532108 - person gbero; 01.12.2014

Это не было исправлено до сих пор. (Android 4.2.1)

person yhpark    schedule 06.12.2012
comment
При использовании Android 4.2.2 Samsung Galaxy S4 проблема все еще существует - person MobDev; 21.08.2013

Я только что потратил несколько часов, чтобы понять, что меня затронула эта проблема.

Кажется, проблема вызвана проверкой орфографии. Когда я отключаю предложения для представления EditText, все правильно собирает мусор.

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

Я действительно не хочу отключать это, так как многим пользователям нужна проверка орфографии. Так что, возможно, есть способ временно включить его, когда поле ввода получает фокус.

Если вам не нужна проверка орфографии, просто добавьте это в элемент EditText в вашем макете xml:

android:inputType="textNoSuggestions"

Кажется, это тоже исправляет.

Изменить:

Только что нашел эту тему, которая, похоже, связана: Устранить утечку SpellCheckerSession?

person Marten    schedule 03.03.2013
comment
Похоже, это не исправит для меня. Android 4.2.2 Samsung Galaxy S4 - person MobDev; 21.08.2013
comment
У меня это тоже не работает, тестирую в эмуляторе, уровень API 17. - person mmm111mmm; 12.03.2014

Я испытываю то же самое. Все мои устройства Gingerbread работают нормально, но при тестировании на моем Galaxy Nexus эта ситуация возникает предсказуемо. Скорее всего, вы переживаете, почему обновления MR1 и 4.0.3 были выпущены так быстро.

person Noah Seidman    schedule 18.12.2011


У меня такая же проблема, я решил ее, скрыв EditText в моем диалоге.

  mEditText.setVisibility(View.GONE);
person otiasj    schedule 03.08.2013
comment
Похоже, это не исправит для меня. Android 4.2.2 Samsung Galaxy S4 - person MobDev; 21.08.2013
comment
Да, похоже, это исправление не работает на устройствах Samsung - person otiasj; 09.04.2014