2012-06-12 13 views
11

Tengo un servicio que envía una intención a mi actividad cada 0.1 segundos. Lo uso para actualizar una implementación personalizada de un cronómetro. Aquí todo va bien. El problema viene cuando quiero actualizar 14 TextView que tengo en una TableView dentro de un Fragmento en mi Actividad. Aquí la aplicación es muy lenta.Varias actualizaciones de TextViews muy lentamente

El método en mi actividad donde recibe la Intención del Servicio:

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     long milis = intent.getLongExtra("milis",0); 
     if(mFragment != null) 
     mFragment.Update(milis); 
    } 
}; 

El código dentro del Fragmento donde puedo actualizar los TextViews:

public void actualizarTiempoJuego(long milis){ 
    // Se recuperan los tiempos acumulados y se aumenta la cantidad pasada como parámetro 
    for(int i=0;i<7;++i) { 
     long mCurrentMilis1 = mVectorMilis1.get(i); 
     long mCurrentMilis2 = mVectorMilis2.get(i); 
     TextView1 t1 = mListaTitularLayoutLocal.get(i); 
     TextView1 t2 = mListaTitularLayoutVisitante.get(i); 
     t1.setText(String.value(milis + mCurrentMilis1)); 
     t2.setText(String.value(milis + mCurrentMilis2)); 
    } 
} 

estoy haciendo nada malo, o ¿Es solo que estoy tratando de hacer algo muy complejo en términos de eficiencia?

+0

me gustaría crear una cadena de 'molinos 'y usarlo 14 veces, en lugar de tratar de crear 14 cadenas idénticas. Y luego use las herramientas de Android para probar si un estándar para bucle, un bucle for-each o el uso de iteradores proporciona los resultados más rápidos. – Sam

+0

@Sam. Esta es una versión ligera. Copié aquí así para que sea más fácil de entender. Lo edito para hacerlo más completo. – gutiory

+0

¿Hay más información que le gustaría para aceptar una respuesta? –

Respuesta

7

@Sherif trae a colación un buen punto acerca de los valores alfa ocultos que empantanan su aplicación mucho. Dependiendo de la plataforma también puede querer comprobar

<application android:hardwareAccelerated="true"... /> 

Otra cosa que se puede ver en que pueden mejorar el rendimiento no está disparando todos los Propósitos. Una vez que comienzas a disparar, estás involucrando al sistema y, dependiendo de cómo se resuelvan, puede tomar un tiempo extra.

Para este problema, me gusta usar Handlers. Son más livianos que intencionados. Es posible que también desee consultar AsyncTask. Esto es básicamente como un hilo, pero también da ganchos que se ejecutan en el subproceso UI para que pueda realizar una operación en segundo plano y actualizar la interfaz de usuario sin tener que publicar ejecutables.

EDITAR: Por último, siempre puede ejecutar sus diseños a través de la herramienta layoutopt. El propio Romain Guy me dijo personalmente que si tu dibujo es demasiado lento, entonces debes sacar menos. Solo mira una captura de pantalla (desde un árbol de vista menos que ideal, pero dentro del máximo) desde la herramienta de creación de perfiles. Puede ver cuánto de los recursos considera ver el dibujo. Es muy importante mantener esto tan delgado como sea posible si desea que su aplicación responda. Profiling View Drawing Resource Consumption

EDITAR: Ya no se llama layoutopt, se llama lint. Compruebe su ~/android-sdk/tools/

+0

HardwareAccelerated no ayudó a mejorar el rendimiento. Estoy buscando la herramienta de enlace. Te lo diré más tarde. – gutiory

+0

Sí. Dije que la aceleración de hardware puede ayudar, dependiendo de su plataforma. También necesita limitar el dibujo y el uso de intenciones. ¿Qué herramienta de enlace me dijiste más tarde? –

+0

Lo siento, quería decir herramienta de pelusa. – gutiory

5

Una vez me enfrenté a una situación en la que un fragmento era muy lento.

Sólo estoy prediciendo que su fragmento tiene algún tipo de alfa y se dibuja en una actividad 'pesada'.

La conclusión es que cada vez que configura el texto de una vista de texto, su jerarquía de vista completa se invalida.

Parece que los fragmentos tienen este defecto. De todos modos, utilice un diseño en lugar del fragmento y compruebe si sigue siendo "lento".


ADEMÁS: Un TextView wrap_content hará mucho más retraso después de un setText que un TextView fill_parent.

+0

¡Su comentario sobre el contenido de wrap_content es caro y resolvió un problema que estaba teniendo! ¡Hurra! Gracias por compartir. – adrianmc

+0

Duuuuuude, has salvado a mi hermano de la vida, gracias !!! Cambiar el ancho de textView a 'matchConstraint' hizo el truco. UI se volvió suave y receptivo. – Mikhail

3

Es probable que se encuentre con ralentizaciones debido a la administración del diseño con TableLayout y TextView. Cada vez que actualiza texto en uno de ellos, debe realizarse una gran cantidad de mediciones de vista para colocar a los personajes en el lugar correcto de la pantalla.En realidad, debería diseñar la aplicación usted mismo utilizando Traceview para averiguarlo. Más información en: http://developer.android.com/tools/debugging/debugging-tracing.html

He tenido exactamente el mismo problema que está viendo con el mismo tipo de diseño (Fragment> TableLayout> Multiple TextViews). Una forma de probar si su configuración de TableLayout/TextView es la culpa es simplemente reemplazar todo eso con un solo TextView. Eso probablemente funcionará bastante bien. Luego ponga sus 14 vistas en FrameLayout o Relative Lay out. Incluso si todos se superponen, aún debería obtener un rendimiento decente, porque la complejidad de las mediciones de vista de TableLayout es lo que realmente está causando la desaceleración.

+0

Hice lo que me dijiste. Comienzo con un solo TextView y todo estaba bien. Pero cuando agregué 5 TextViews más, se volvió lento de nuevo. – gutiory

+0

¿Eliminó TableLayout antes de esta prueba?Estoy 99% seguro de que el retraso que está viendo proviene de la medición de la Vista necesaria para alinear correctamente varias filas de un diseño de tabla combinado con la medición de TextViews con texto dinámico. – Josh

+0

Sí. Eliminé TableLayout como sugirió. Cambio el fragmento que incluía TableLayout para las textviews. – gutiory

0

Como alguien dijo que puede usar HardwareAccelerated pero esta no es una gran solución, desperdiciará ram y cpu si no puede resolverlo de otra manera. Una solución probablemente más segura es reducir el número de TextView. Intenta reducir de 14 a 7 e irá dos veces más rápido. Por lo general, es difícil hacerlo, pero si coloca los objetos en una posición estratégica, un par de TextView uno encima de otro pueden estar juntos si hace un TextView con dos líneas. Y no olvide que findViewById es tan caro, si va a utilizar un objeto de vista a menudo lo encontrará una sola vez y mantendrá su referencia.

0

Los puntos de referencia siempre son útiles para determinar de dónde proviene realmente la lentitud, pero me siento bastante confiado al sugerir que enviar un Intento es probablemente mucho más lento que actualizar 14 TextViews. Enviar 10 Intents por segundo es una señal de que estás haciendo las cosas mal (TM). Esto no es para lo que son.

¿Estoy haciendo algo mal, o es solo que estoy tratando de hacer algo muy complejo en términos de eficiencia?

La actualización de 14 TextViews por segundo no es inherentemente compleja; Debería poder lograrlo fácilmente con un diseño de aplicación más apropiado. ASyncTask o Handler vienen a la mente como posibles herramientas, pero es difícil saber qué es lo mejor sin saber más acerca de lo que estás tratando de hacer exactamente.

+0

He usado un Hanlder para actualizar las TextViews, pero sigo teniendo el mismo comportamiento. – gutiory

+0

@gutiory ¿Se deshizo del Servicio y los Intentos? Agregar un Handler además de eso no va a hacer las cosas más rápido. Sugiero usar una arquitectura diferente con Handler o AsyncTask * en su lugar * de un Servicio e Intenciones. –

0
  • Usted puede tratar de declarar VARs fuera del bucle:

    public void actualizarTiempoJuego(long milis){ 
        // Se recuperan los tiempos acumulados y se 
        // aumenta la cantidad pasada como parámetro 
    
        long mCurrentMilis1; 
        long mCurrentMilis2; 
        TextView1 t1; 
        TextView1 t2; 
    
        for(int i=0;i<7;++i) { 
         mCurrentMilis1 = mVectorMilis1.get(i); 
         mCurrentMilis2 = mVectorMilis2.get(i); 
         t1 = mListaTitularLayoutLocal.get(i); 
         t2 = mListaTitularLayoutVisitante.get(i); 
         t1.setText(String.value(milis + mCurrentMilis1)); 
         t2.setText(String.value(milis + mCurrentMilis2)); 
        } 
    } 
    
  • Y para setText() con tipo mixto, puede intentar setText("" + milis + mCurrentMilis2);

+0

tal vez "onReceive" bloquea en algún lugar, y el uso de una asynctask para la actualización de la interfaz de usuario podría acelerar el proceso, también – Arcadien

Cuestiones relacionadas