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)
- Android Eclipse DDMS> Heap> Causa gris de GC
- Mapa de bits extraño con 1 Mb de Heap
- Cómo analizar la memoria usando android studio
- Razones por las que mi aplicación Android se bloquea en mi teléfono de forma consistente, pero no en mi emulador
- Dirección heap no válida y señal fatal 11
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:
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 …
- El número de referencias de método en un archivo .dex supera los 64K
- Tutoriales o ejemplos para la depuración de la memoria de Android
- Android "cerrar la fuerza" lo que exactamente sucede con la memoria
- Problema de memoria de mapa de bits de Android - Error: falta de memoria en una asignación de 8294416 bytes
- Gráficos Android gran consumo de memoria montón? - LibGDX
- Consulta sobre propiedades en /system/build.prop
- Android: Error de OutOfMemory y el backstack
- CORRUPCIÓN DE MEMORIA HEAP EN los errores dlmalloc o dlfree y SIGSEGV en Android ICS 4.0
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
.