EditText que causa la pérdida de memoria

Intro:

Tengo una aplicación que tiene la siguiente estructura: ActionBar arriba (ActionBarSherlock) ViewPagerIndicator debajo de eso (para las pestañas) ViewPager (hosts Fragmentos)

Tengo un problema que uno de mis fragmentos está causando una pérdida bastante mayor de la memoria. Entendí el problema hasta el siguiente caso:

El fragmento que está causando la fuga no hace nada sino inflar un diseño en su método onCreateView . Esto se hace de la siguiente manera:

 return inflater.inflate(R.layout.filter_auctions_fragment, container, false); 

Nada inusual aquí.

El archivo de diseño sólo incluye un ScrollView , LinearLayout y dos EditText s en él (incluye más cosas normalmente pero redujo el problema a sólo estas vistas para hacerlo más simple).

Ahora el código que se utiliza para agregar el fragmento: mTabsAdapter.addTab (tabName, ProblematicFragment.class);

mTabsAdapter es una instancia de TabsAdapter , una clase que extiende FragmentPagerAdapter de la biblioteca de soporte. Es bastante estándar por lo que no estoy incluyendo la fuente para mantener esta pregunta tan breve como sea posible.

Ahora la parte divertida:

Esto es lo que sucede con el montón cuando giro mi dispositivo de ida y vuelta unas cuantas veces:

 12-28 12:26:27.180: D/dalvikvm(18841): GC_CONCURRENT freed 530K, 7% free 10701K/11436K, paused 4ms+7ms, total 58ms 12-28 12:26:27.180: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 24ms 12-28 12:26:28.270: D/dalvikvm(18841): GC_CONCURRENT freed 737K, 8% free 11048K/11964K, paused 4ms+5ms, total 53ms 12-28 12:26:29.510: D/dalvikvm(18841): GC_CONCURRENT freed 789K, 8% free 11464K/12436K, paused 5ms+5ms, total 42ms 12-28 12:26:30.640: D/dalvikvm(18841): GC_CONCURRENT freed 888K, 9% free 11919K/12984K, paused 4ms+5ms, total 52ms 12-28 12:26:31.810: D/dalvikvm(18841): GC_CONCURRENT freed 903K, 8% free 12421K/13500K, paused 3ms+8ms, total 58ms 12-28 12:26:33.800: D/dalvikvm(18841): GC_CONCURRENT freed 1092K, 9% free 13005K/14272K, paused 4ms+6ms, total 59ms 12-28 12:26:33.800: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 20ms 12-28 12:26:36.000: D/dalvikvm(18841): GC_CONCURRENT freed 1355K, 11% free 13518K/15048K, paused 3ms+8ms, total 74ms 12-28 12:26:36.000: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 19ms 12-28 12:26:38.110: D/dalvikvm(18841): GC_CONCURRENT freed 1450K, 11% free 14106K/15720K, paused 3ms+11ms, total 72ms 12-28 12:26:40.450: D/dalvikvm(18841): GC_CONCURRENT freed 1530K, 11% free 14807K/16516K, paused 2ms+15ms, total 75ms 12-28 12:26:40.450: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 29ms 12-28 12:26:43.030: D/dalvikvm(18841): GC_CONCURRENT freed 1682K, 11% free 15591K/17452K, paused 3ms+10ms, total 66ms 12-28 12:26:43.030: D/dalvikvm(18841): WAIT_FOR_CONCURRENT_GC blocked 32ms 

Claramente, una fuga de memoria. Sí, sé que hace que la actividad sea recreada desde cero y esto es lo que quiero porque tengo diferentes diseños para modos de paisaje y retrato. No obstante, no debe causar una pérdida de memoria.

He encontrado la fuente de este problema. Son los dos EditText que mencioné anteriormente. Tan pronto como los quite del diseño y haga la misma prueba (gire hacia adelante y hacia atrás). Estos son los mensajes de GC que obtengo:

 12-28 12:21:41.270: D/dalvikvm(17934): GC_CONCURRENT freed 534K, 7% free 10853K/11576K, paused 3ms+7ms, total 44ms 12-28 12:21:42.560: D/dalvikvm(17934): GC_CONCURRENT freed 818K, 9% free 11113K/12108K, paused 11ms+9ms, total 95ms 12-28 12:21:44.680: D/dalvikvm(17934): GC_CONCURRENT freed 1036K, 10% free 11313K/12528K, paused 3ms+6ms, total 54ms 12-28 12:21:44.680: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 15ms 12-28 12:21:47.420: D/dalvikvm(17934): GC_CONCURRENT freed 1089K, 10% free 11510K/12780K, paused 2ms+6ms, total 79ms 12-28 12:21:47.420: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 39ms 12-28 12:21:50.200: D/dalvikvm(17934): GC_CONCURRENT freed 1317K, 12% free 11461K/12956K, paused 4ms+13ms, total 84ms 12-28 12:21:53.210: D/dalvikvm(17934): GC_CONCURRENT freed 1629K, 14% free 11148K/12956K, paused 3ms+7ms, total 47ms 12-28 12:21:55.580: D/dalvikvm(17934): GC_CONCURRENT freed 1056K, 13% free 11302K/12956K, paused 4ms+7ms, total 59ms 12-28 12:21:57.280: D/dalvikvm(17934): GC_CONCURRENT freed 1306K, 14% free 11200K/12956K, paused 5ms+5ms, total 82ms 12-28 12:21:59.420: D/dalvikvm(17934): GC_CONCURRENT freed 1035K, 12% free 11408K/12956K, paused 3ms+7ms, total 55ms 12-28 12:22:01.990: D/dalvikvm(17934): GC_CONCURRENT freed 1392K, 13% free 11352K/12956K, paused 4ms+9ms, total 54ms 12-28 12:22:01.990: D/dalvikvm(17934): WAIT_FOR_CONCURRENT_GC blocked 30ms 

¡Ahora eso es lo que quiero ver!

¿¡POR QUÉ!?

¿Puede alguien decirme por qué esto está sucediendo? Me gustaría añadir que no estoy guardando una referencia a estos EditText objeto en cualquier parte de mi aplicación (normalmente lo hago, pero incluso cuando he eliminado todos ellos para fines de prueba de la fuga sigue ocurriendo).

Bonus – MAT Imágenes de la fuga:

Camino a GC Roots (whtout soft / weak refs) para mi Actividad

Camino a las raíces de GC (whtout suave / refs débiles) para mi "ProblemmaticFragment"

Como se puede ver hay 16 casos del Fragmento Y la Actividad, mientras que debe haber solo uno.

EDITAR:

Me di cuenta de que cuando i agregar manualmente el fragmento en una actividad diferente (utilizando FragmentManager.beginTransaction() ) la fuga no se produce! Estoy completamente confundido ahora …

EDIT2:

Quitar el atributo android:id del EditText arregla … Pero ahora son bastante inútiles …

He encontrado una solución que se ajusta a mis necesidades.

Seguí el problema hasta widget.EditableInputConnection . Que creo que hace la búsqueda en el sistema de sugerencias. También es responsable de retener mi Actividad, causando así una pérdida de memoria.

No necesito las sugerencias, así que quería apagarlo. Sin embargo, ha demostrado ser difícil. EditText.setInputType no funcionó, ni en xml ni en código.

Terminé haciendo lo siguiente. La magia está sucediendo en onCreateInputConnection() :

 public class MyEditText extends TextView { public MyEditText(Context context) { this(context, null); } public MyEditText(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.editTextStyle); } public MyEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return null; } @Override protected boolean getDefaultEditable() { return true; } @Override protected MovementMethod getDefaultMovementMethod() { return ArrowKeyMovementMethod.getInstance(); } @Override public Editable getText() { return (Editable) super.getText(); } @Override public void setText(CharSequence text, BufferType type) { super.setText(text, BufferType.EDITABLE); } /** * Convenience for {@link Selection#setSelection(Spannable, int, int)}. */ public void setSelection(int start, int stop) { Selection.setSelection(getText(), start, stop); } /** * Convenience for {@link Selection#setSelection(Spannable, int)}. */ public void setSelection(int index) { Selection.setSelection(getText(), index); } /** * Convenience for {@link Selection#selectAll}. */ public void selectAll() { Selection.selectAll(getText()); } /** * Convenience for {@link Selection#extendSelection}. */ public void extendSelection(int index) { Selection.extendSelection(getText(), index); } @Override public void setEllipsize(TextUtils.TruncateAt ellipsis) { if (ellipsis == TextUtils.TruncateAt.MARQUEE) { throw new IllegalArgumentException("EditText cannot use the ellipsize mode " + "TextUtils.TruncateAt.MARQUEE"); } super.setEllipsize(ellipsis); } } 

Donde el truco es rechazar el InputConnection. Esto elimina las sugerencias y elimina la pérdida de memoria.

Espero que esto le ayuda a ..

Yo estaba enfrentando el mismo problema con un Samsung Galaxy S3.

La solución de @aslakjo no funcionó para mí. Tenía sugerencias deshabilitadas ya

Terminé reemplazando el android:id por android:tag para el EditText en el diseño XML. Ahora está funcionando bien, mis fragmentos que estaban contenidos en un viewpager están correctamente recolectados cuando ya no son visibles, no me preguntes por qué.

Este dispositivo podría registrar algo basado en la presencia de un id .

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.