Cuando trabajes con reglas de conservación, es importante alcanzar el nivel adecuado de especificidad para asegurarte de ver los beneficios y, al mismo tiempo, mantener el comportamiento de tu app. Consulta las siguientes secciones para obtener información sobre los buenos patrones y las cosas que debes evitar en las reglas de conservación.
Buenos patrones en las reglas de conservación
Las reglas de conservación bien definidas son lo más específicas posible y cumplen con los siguientes patrones:
Para la especificación de la clase, siempre especifica una clase, una clase base o una clase anotada específicas, si es posible, como se muestra en los siguientes ejemplos:
-keepclassmembers class com.example.MyClass { void someSpecificMethod(); }-keepclassmembers ** extends com.example.MyBaseClass { void someSpecificMethod(); }-keepclassmembers @com.example.MyAnnotation class ** { void someSpecificMethod(); }Siempre que sea posible, usa anotaciones en tu código fuente y, luego, segmenta esas anotaciones directamente en tus reglas de conservación. Esto crea un vínculo claro y explícito entre tu código y las reglas que lo conservan, lo que hace que tu configuración sea más sólida, fácil de comprender y menos propensa a fallas cuando cambia el código.
Por ejemplo, en el siguiente fragmento, se muestra cómo puedes conservar la clase MyClass, así como otras clases anotadas con
@com.example.DisplayComponent:// In the source code @com.example.DisplayComponent class MyClass { /* ... */ } // In the keep rules -keep @com.example.DisplayComponent class * {*;}Te recomendamos que nombres tus anotaciones de manera que proporcionen un contexto significativo sobre por qué se conservan partes del código. Por ejemplo, usa
@DisplayComponentpara una app en la que los componentes de visualización requieren que se conserven algunas partes.Siempre que sea posible, se debe declarar la especificación del miembro y solo hacer referencia a las partes de la clase que se deben conservar para que la app funcione. Se recomienda no aplicar una regla a toda una clase definiendo el alcance del miembro opcional como
{ *; }, a menos que sea estrictamente necesario.-keepclassmembers com.example.MyClass { void someSpecificMethod(); void @com.example.MyAnnotation *; }Si usas la opción global
repackageclasses, evita especificar el nombre del paquete opcional. Esto genera archivos DEX más pequeños, ya que el prefijo del paquete se omite en los nombres de las clases reempaquetadas.Mantén las reglas de conservación para todos los elementos a los que se accede por reflexión. Incluso si R8 conserva esos elementos sin reglas de conservación explícitas, es fundamental mantener las reglas reales, ya que los cambios futuros en el código podrían hacer que R8 ya no conserve estos elementos.
Si no puedes cumplir con estos lineamientos, puedes aislar temporalmente el código que debe conservarse en un paquete dedicado y aplicar tu regla de conservación al paquete. Sin embargo, esta no es una solución a largo plazo. Para obtener más información, consulta Adopta optimizaciones de forma incremental. Para usar una regla de conservación para un paquete, define una regla de conservación como se muestra en el siguiente ejemplo:
-keepclassmembers class com.example.pkg.** { *; }
Elementos que debes evitar
La sintaxis de las reglas de conservación tiene muchas opciones, pero, para obtener beneficios de rendimiento sostenibles y medibles, te recomendamos que no uses las siguientes:
- No uses reglas de conservación para todo el paquete, como
-keep class com.example.pkg.** { *; }, a largo plazo. Se pueden usar de forma temporal para solucionar problemas cuando se configura R8. Para obtener más información, consulta Cómo limitar el alcance de la optimización. En general, ten cuidado con los comodines y asegúrate de conservar solo el código que necesitas. - Cuando sea posible, evita las bibliotecas que te sugieran copiar y pegar reglas de conservación cuando las uses, en especial las reglas de conservación para todo el paquete. Las bibliotecas diseñadas para funcionar bien en Android deben evitar la reflexión siempre que sea posible y incorporar reglas de conservación del consumidor cuando sea necesario.
- Evita usar el operador de inversión
!en las reglas de conservación, ya que podrías aplicar una regla de forma no intencional a casi todas las clases de tu aplicación.
Si no puedes seguir estas reglas, es posible que estés usando mucha reflexión de extremo abierto, por lo que deberías evitar la reflexión o la biblioteca que usa la reflexión (consulta el caso de estudio de Gson).