Skip to content

Most visited

Recently visited

navigation

Verificación del comportamiento de la app en el tiempo de ejecución de Android (ART)

El tiempo de ejecución de Android (ART) es el tiempo de ejecución predeterminado para dispositivos con Android 5.0 (nivel de API 21) y versiones posteriores. Este tiempo de ejecución ofrece varias funciones que mejoran el rendimiento y la fluidez de la plataforma de y las apps de Android. Puedes encontrar más información sobre las nuevas funciones del ART en Introducción al ART.

Sin embargo, algunas técnicas que funcionan en Dalvik no sirven en ART. En este documento, verás aspectos que debes observar al realizar la migración de una app existente para que sea compatible con el ART. La mayoría de las apps solo deben funcionar cuando se ejecutan con el ART.

Tratamiento de problemas de recolección de elementos no usados (GC)

Con Dalvik, en las apps a menudo resulta útil llamar de manera explícita a System.gc() para solicitar la colección de elementos no usados (GC). Esto debe ser mucho menos necesario con el ART, en particular si invocas a una colección de elementos no usados para evitar casos del tipo GC_FOR_ALLOC o reducir la fragmentación. Puedes verificar el tiempo de ejecución en uso llamando a System.getProperty("java.vm.version"). Si el ART se encuentra en uso, el valor de la propiedad es "2.0.0" o posterior.

Además, a fin de mejorar la administración de memoria, se encuentra bajo desarrollo un recolector con compactación de elementos no usados en el proyecto de código abierto de Android (AOSP). Por lo tanto, debes evitar usar técnicas que no sean compatibles con recolector con compactación de elementos no usados (como guardar punteros en datos de instancias de objetos). Esto tiene particular importancia para las apps que usan la interfaz nativa de Java (JNI). Para obtener más información, consulta Prevención de problemas de la JNI.

Prevención de problemas de la JNI

La JNI del ART es un poco más estricta que la de Dalvik. Se recomienda en particular usar el modo CheckJNI para capturar problemas comunes. Si tu app usa código C/C++ , debes revisar el siguiente artículo:

Depuración de la JNI de Android con CheckJNI

Verificación del código de la JNI en busca de problemas de recolección de elementos no usados

En el caso del ART, se encuentra en desarrollo un recolector con compactación de elementos no usados en el proyecto de código abierto de Android (AOSP). Una vez que el recolector con compactación de elementos no usados se encuentra en uso, los objetos pueden quitarse de la memoria. Si usas código C/C++, no realices operaciones que no sean compatibles con el recolector con compactación de elementos no usados. Hemos mejorado CheckJNI para identificar algunos problemas potenciales (como se describe en Cambios de referencia local de JNI en ICS).

Un área que debe observarse en particular es el uso de Get...ArrayElements() y las funciones Release...ArrayElements(). En tiempos de ejecución con recolector sin compactación de elementos no usados, las funciones Get...ArrayElements() generalmente muestran una referencia para la memoria actual que respalda el objeto de matriz. Si realizas un cambio en uno de los elementos de matriz que se muestran, el objeto de matriz se cambia solo (y los argumentos para Release...ArrayElements() generalmente se ignoran). Sin embargo, si se usa un recolector con compactación de elementos no usados, las funciones Get...ArrayElements() pueden mostrar una copia de la memoria. Si no usas bien la referencia cuando se use el recolector con compactación de elementos no usados, se pueden producir daños en la memoria u otros problemas. Por ejemplo:

Administración de errores

La JNI del ART genera errores en varios casos en los cuales no sucede lo mismo con Dalvik. (Una vez más, puedes capturar muchos casos realizando pruebas con CheckJNI).

Por ejemplo, si se llama RegisterNatives con un método que no existe (tal vez porque se quitó el método a través de una herramienta como ProGuard), ART generará NoSuchMethodErrorcorrectamente:

08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main
08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError:
    no static or non-static method
    "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I"
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.nativeLoad(Native Method)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.doLoad(Runtime.java:421)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.loadLibrary(Runtime.java:362)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.System.loadLibrary(System.java:526)

ART también carga un error (visible en logcat) si se llama a RegisterNatives sin métodos:

W/art     ( 1234): JNI RegisterNativeMethods: attempt to register 0 native
methods for <classname>

Además, las funciones de JNI GetFieldID() y GetStaticFieldID() generan NoSuchFieldError correctamente en lugar de simplemente mostrar null. De modo similar, GetMethodID() y GetStaticMethodID() ahora genera NoSuchMethodErrorcorrectamente. Esto puede ocasionar fallas en CheckJNI debido a las excepciones que no se manejan o las excepciones que se generan en emisores de Java de código nativo. Esto atribuye particular importancia a la prueba de apps compatibles con el ART a través del modo CheckJNI.

El ART supone que los usuarios de los métodos de JNI CallNonvirtual...Method() (como CallNonvirtualVoidMethod()) apliquen la clase de declaración de los métodos, no subclases, como lo requiere la especificación de JNI.

Prevención de problemas de tamaño de pila

Dalvik tenía pilas separadas para el código nativo y el código Java con un tamaño de pila predeterminado de 32 KB y un tamaño de pila nativa predeterminado de 1 MB. El ART tiene una pila unificada para una mejor localidad. Generalmente, el tamaño de la pila del ART Thread debe ser aproximadamente el mismo que para Dalvik. Sin embargo, si configuras los tamaños de las pilas de modo explícito, tal vez debas repasar esos valores para apps que se ejecutan en el ART.

Cambios de modelo de objeto

Dalvik permitió de modo incorrecto que las subclases anulen los métodos privados de paquetes. El ART emite una precaución en dichos casos:

Before Android 4.1, method void com.foo.Bar.quux()
would have incorrectly overridden the package-private method in
com.quux.Quux

Si intentas anular un método de la clase en un paquete diferente, declara el método como public o protected.

AhoraObject tiene campos privados. Las apps que se reflejan en campos en sus jerarquías de clases deben procurar no intentar observar los campos de Object. Por ejemplo, si realizas una iteración en una jerarquía de clase como parte de un framework de serialización, detente cuando

Class.getSuperclass() == java.lang.Object.class
en lugar de continuar hasta que el método muestre null.

El proxy InvocationHandler.invoke() recibe null si no hay argumentos en lugar una de matriz vacía. Este comportamiento se documentó previamente, pero no se manejó de modo correcto en Dalvik. En las versiones previas de Mockito existen complicaciones con esto. Por ello, usa una versión actualizada de Mockito cuando realices pruebas con el ART.

Solución de problemas de compilación de AOT

La compilación de Java por adelantado (AOT) de ART debe funcionar con todos los códigos estándares de Java. La compilación se lleva a cabo con la herramienta dex2oat del ART. Si encuentra algún problema relacionado con dex2oat en el momento de la instalación, notifícalo (consulta Informe de problemas) para que los podamos corregir lo más pronto posible. Algunos problemas que deben tenerse en cuenta:

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)