Почему EditText сохраняет контекст своей деятельности в Ice Cream Sandwich - PullRequest
15 голосов
/ 14 декабря 2011

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

Ответы [ 6 ]

8 голосов
/ 14 декабря 2011

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

7 голосов
/ 06 декабря 2012

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

4 голосов
/ 04 марта 2013

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

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

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

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

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

android:inputType="textNoSuggestions"

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

Изменить:

Только что нашел этот поток, который, кажется, связан: Обход утечки SpellCheckerSession?

0 голосов
/ 03 августа 2013

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

  mEditText.setVisibility(View.GONE);
0 голосов
/ 18 декабря 2011

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

0 голосов
/ 14 декабря 2011

Вы столкнулись с ситуацией, описанной в разделе ресурсов Android по утечкам памяти .Также смотрите эту страницу для некоторых решений.

...