Optimización de la aplicación de Android antes del lanzamiento [cerrado]

120

Estoy en una situación " especial " acerca de la eficiencia de mi programa. Ahora estoy en una fase en la que necesito mejorar el rendimiento de la aplicación y reducir el consumo de batería .

Antes de la pregunta:

Ahora, tengo curiosidad por saber acerca de las correcciones especiales de otros desarrolladores que han utilizado para optimizar sus propias aplicaciones. Cosas que los usuarios tal vez nunca reconozcan o a las que nunca presten atención. Sin embargo, las correcciones aumentarán la duración de la batería o ayudarán a mejorar el mantenimiento de la aplicación.

Entonces, ¿cuál es su (s) truco (s) de optimización únicos?

Estoy en una situación particular en la que realmente estoy buscando conocimiento y creo que esta será una gran oportunidad para compartir el conocimiento de los desarrolladores sobre una situación en la que todos han estado.

Por favor, vote las grandes respuestas, ya que esto animará a los grandes desarrolladores a compartir sus conocimientos.

Wroclai
fuente
2
Dado que, en última instancia, la eficiencia se reduce a no hacer nada que no sea necesario (o más a menudo de lo necesario), creo que mucho dependerá de los tipos de cosas que su aplicación tenga que lograr ... Sin especificar eso, todos lo que puede hacer es obtener una colección de "sospechosos habituales"
Chris Stratton
1
@Chris Stratton: Bueno, tienes razón. Pero también, los "sospechosos habituales" o una pequeña respuesta sobre un truco específico facilitarán que otros tomen una decisión si esa "suposición" es lo que están buscando (y si es útil para su situación específica).
Wroclai
Es ridículo cuántas preguntas realmente interesantes se cierran en este sitio.
Patrick

Respuestas:

68

En algún momento, llegará al punto en el que usar trucos conocidos llegará a sus límites. Lo mejor que puede hacer en este punto es perfilar su código y ver qué áreas son los cuellos de botella según sus requisitos específicos.

Investigando el uso de RAM usando MAT y usando Traceview : un artículo sobre cómo usar las herramientas para perfilar su aplicación.

profano
fuente
¡Gracias! Me gustan mucho las respuestas con recursos. :-)
Wroclai
1
Lea esta entrada de blog. medium.com/@hammad_tariq/…
Developine
37

Rastrea y aplasta las asignaciones. Cuanto más asigne, más a menudo tendrá que ejecutarse el recolector de basura, lo que evitará que el proceso haga cualquier otra cosa durante períodos de tiempo relativamente largos, como 100 ms aproximadamente.

La mejor herramienta que conozco para esto es el Allocation Tracker incluido en DDMS .

GC no solo puede tener un impacto en la experiencia del usuario, sino que las asignaciones superfluas y GC consumen algunos recursos informáticos.

Aquí tienes un ejemplo y un pequeño truco. En mi aplicación, tengo un reloj que muestra la hora actual (audio), incluida la décima de segundo. Esto se actualiza con frecuencia. Y TextView realiza asignaciones internamente cada vez que llama a setText () con CharSequence. Pero no asigna nada con la variante setText (char [] text, int start, int len). Esto no está documentado y nadie respondió cuando le pregunté.

Hay muchos como este. Y esta es una de las razones por las que mi aplicación contiene un 50% de código nativo (pero hay otras razones).

Aparte de esto, puedo recomendarle que experimente con ProGuard . Realiza varias pasadas de optimización y registra información como métodos no utilizados dentro del proyecto, lo que puede ayudarlo a eliminar los restos de su código.

olivierg
fuente
1
¡Gran respuesta! Se agradecen los trucos concretos.
Wroclai
22

Si su aplicación tendrá mucho tiempo de pantalla, use negro siempre que pueda . Eso reducirá el consumo de batería de la peor parte del dispositivo: la pantalla, especialmente en los teléfonos y tabletas AMOLED.

Aleadam
fuente
El uso prudente de los colores oscuros significa una victoria para la batería.
Robert Massaioli
7
Por otro lado, el negro consume más energía que el blanco en las pantallas LCD, porque la luz (proveniente de la luz de fondo) comienza en blanco y debe bloquearse activamente para producir negro. [ scientificamerican.com/article.cfm?id=fact-or-fiction-black-is ] En pocas palabras: No cuente demasiado con esta optimización de color.
Sparky
16

Para aplicaciones con múltiples actividades, verifique que no está reiniciando actividades que solo necesitan ser llevadas al frente usando los indicadores de Intención apropiados. Compruebe que su montón está bajo control y que no se están creando vistas, enlaces y contextos innecesarios.

Encuentro que la mejor herramienta para mostrarte todo esto mientras se ejecuta la aplicación es:

adb shell dumpsys meminfo 'your apps package name'
NickT
fuente
1
Oh, eso era nuevo. ¡Gracias por compartir!
Wroclai
15

Cuando utilice SQLlite, ponga especial atención en los índices. No asumas nada. Obtuve tremendas aceleraciones en Zwitscher, cuando coloqué índices en columnas que se usan comúnmente para la búsqueda.

Heiko Rupp
fuente
13

Algunos consejos que pueden ayudarlo a optimizar su aplicación en términos de IU :

  • usar convertViewpara adaptadores de lista: sería muy costoso crear una nueva vista en el interior, Adapter.getView()ya que esta rutina se llama para cada posición en la lista. El uso le convertViewpermite reutilizar la vista ya creada. Un buen ejemplo (junto con el uso de ViewHolder) se puede encontrar en ApiDemos .

  • Puede suceder que sus diseños no estén completamente optimizados y puedan mejorarse (por ejemplo, mediante la combinación o eliminación de elementos principales). Layoutopt de la herramienta de Android encontrará tal situación para usted. Se puede utilizar con HierarchyViewer para inspeccionar vistas individuales. Más info aquí .

  • eliminar el elemento de diseño de fondo: el marco de trabajo de Android solía tener (¿todavía tiene?) un problema para detectar qué vistas se deben dibujar. Existe la posibilidad de que su diseño de fondo (predeterminado) se dibuje solo para luego ser ocultado por su interfaz de usuario opaca. Para deshacerse de este dibujo inútil, simplemente elimine el fondo dibujable.

Se puede hacer usando un estilo personalizado.

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

Algunos consejos que pueden ayudarlo a optimizar su aplicación en términos de uso de la batería :

  • Verifique el tipo de red y espere hasta que el usuario ingrese al área con wifi o 3G (y no roaming) y solo entonces permítale usar la conexión

  • use gzip para datos textuales siempre que sea posible para acelerar la descarga y el análisis

  • reciclar objetos java complejos como XmlPullParserFactory/ BitmapFactory/ StringBuilder/ Matcheretc.

Para obtener más trucos sobre la batería, consulte Codificación de por vida: duración de la batería .

youri
fuente
"reciclar objetos java complejos como ..." ¿Cómo? mientras que Java tiene GC
Yousha Aleayoub
9

Algo en lo que pensar: NO use en exceso String, por ejemplo, en un bucle enorme. Esto creará una gran cantidad de objetos String que deben someterse a GC. El ejemplo de "Codificación incorrecta" producirá 2 objetos de cadena en cada bucle. El siguiente ejemplo producirá solo una Cadena final y un solo constructor de cadenas. Esto marca una gran diferencia al optimizar grandes bucles para la velocidad. Usé mucho el constructor de cadenas al hacer mi aplicación de Android Wordlist Pro, y se volvió realmente rápido cuando repasé 270000 palabras en poco tiempo.

    //Bad coding:
    String s = "";
    for(int i=0;i<999999;i++){
        s = "Number=";
        s = s + i;
        System.out.println(s);
    }

    //Better coding
    final String txt = "Number=";
    StringBuilder sb = new StringBuilder();
    for(int i=0;i < 999999;i++){
        sb.setLength(0);
        sb.append(txt);
        sb.append(i);
        System.out.println(sb);
    }

Escribí una entrada de blog más extensa sobre el asunto. leer aquí

Ernell
fuente
6

Supongo que el uso de variables "finales" en todos los lugares donde sea posible también podría mejorar la velocidad de ejecución.

Stan
fuente
1
Recuerdo haber leído eso en alguna parte, ¿podrías proporcionar un enlace?
Wesley Wiser
1
No estoy tan seguro de que sea cierto para las variables finales, pero puede serlo para las variables finales estáticas; consulte stackoverflow.com/questions/3117770/…
Alistair Collins
No puedo proporcionar el enlace, pero encontré un aviso al respecto en "Guía para principiantes de Android" por Reto Meier (19 de mayo de 2010) / Google IO. Es breve, se puede descargar gratis y tiene buenos consejos sobre cómo crear una buena aplicación.
Stan
2
Las variables finales podrían hacer que el código sea más eficiente porque significará que todos los objetos serán GC en la misma ejecución. No en diferentes momentos según el momento en que los establezca como nulos.
Robert Massaioli
1
Pregunta: ¿No lo hace el compilador explícitamente por usted? Creo que debería hacerlo en su fase de análisis de código.
Pawan
6

Optimice sus imágenes PNG con herramientas como OptiPNG y PNGCrush para reducir algunos (kilo) bytes del tamaño de APK. Los consejos de optimización de imágenes para sitios web también se aplican aquí: use formatos de imagen apropiados, juegue con compresión JPG, considere usar transparencias binarias en lugar de transparencias de 8 bits, etc.

Si envía grandes archivos PNG con canal alfa, puede cambiar algo de tamaño APK para la velocidad de arranque y utilizar los archivos JPG independientes para los canales RGB y A .

Si está realizando conexiones HTTP, verifique que su cliente HTTP utilice compresión de contenido. Si almacena en caché las respuestas HTTP recibidas, verifique que comprenda y utilice correctamente los encabezados HTTP relacionados con el almacenamiento en caché.

Pēteris Caune
fuente
¡Gracias por tu información! ¡Nunca había oído hablar de esto!
Wroclai
5

Si tiene operaciones de red, intente reutilizar la misma instancia de httpclient. Evite el uso de expresiones regulares.

Naresh
fuente
¿Razón? ¿puedes explicar porque?
Yousha Aleayoub
5

Intente usar DDMS para rastrear todos los subprocesos que se ejecutan en el sistema. Por ejemplo, he notado que estaba usando webview para mostrar contenido html, noté que crea pocos hilos para la gestión de sesiones de gestión de cookies, etc., lo que aumentó mi huella de memoria. Entonces, a menos que tenga una necesidad seria de mostrar html complejo, intente usar la clase de utilidad normal "Html" en Android para mostrar contenido html. Esto puede ser útil para las personas que muestran Eula, ya que eula typicall contiene texto html.

Si tiene que realizar operaciones de red, intente usar AndroidHttpClient si es un principiante, tiene algunas buenas capacidades para almacenar en caché sesiones SSL y todo lo que realmente ayuda a mejorar su rendimiento. Establezca siempre los tiempos de espera de la conexión del socket en algo alrededor de 60 segundos o algunos valores finitos porque los tiempos de espera infinitos pueden causar interbloqueos, especialmente si deja caer su conexión durante el protocolo de enlace ssl.

Naresh
fuente
4

Evite usar XPath si puede analizar su entrada XML utilizando rutinas de manipulación de cadenas para obtener el texto entre las etiquetas. He probado y puedo confirmar una mejora de 10 veces en este caso, en un conjunto de datos de 50000 elementos, en un HTC Desire.

luvieere
fuente
3

Sé que me uniré un poco más tarde a esta conversación, pero sería perfecto tener muchos buenos consejos en un solo lugar, así que espero que este hilo esté vivo y actualizado con bastante frecuencia. Mis consejos:

  • No bloquee el hilo de la interfaz de usuario con trabajos costosos, el usuario se irá si no hay respuesta de la aplicación (use AsyncThreads).
  • Utilice LINT , una nueva herramienta que analiza las fuentes de los proyectos de Android en busca de posibles errores.

..será actualizado..

Ewoks
fuente