Inicio > Android, Java > ProGuard: Optimiza, reduce y ofusca el código de tus aplicaciones Android

ProGuard: Optimiza, reduce y ofusca el código de tus aplicaciones Android


proguard

Cuando creamos aplicaciones para dispositivos móviles debemos tener en cuenta la limitaciones de estos. si bien en la gama alta apenas existe, hay que considerar también los móviles de gama baja.

Una de tantas limitaciones es la memoria interna, por lo que reducir el tamaño de nuestra aplicación debe ser algo a considerar, y en esto ProGuard nos puede ayudar una forma muy simple.

En lo primero que nos ayudará ProGuard es en eliminar todas las clases no usadas de nuestro APK. Si utilizáis librerías externas en vuestro proyecto, es bastante usual usar solo una parte de la librería, dejando multitud de clases inútiles ocupando espacio. ProGuard detectará estas clases y las eliminará del archivo resultante, disminuyendo bastante el tamaño de la aplicación en determinados casos.

Por otro lado, como bien sabéis, Java compila a bytecodes, un lenguaje intermedio entre código Java y ensamblador, y en este deja los nombres de clases, variables y métodos “tal cual”, y como comprenderéis, el propio nombre ocupa unos cuantos bytes. Mientras que el nombre de la variable alumnos serían 7 bytes, una llamada a sería solo 1, y con programas con cientos de variables, métodos y clases, al final se nota. Pues bien, ProGuard ofusca nuestro código cambiando el nombre de las variables, métodos y clases, haciendo que ocupen mucho menos y, de paso,  incomprensible a los curiosos que intenten usar un decompilador.

En el caso de Android, usarlo es extremadamente fácil, basta con abrir el fichero en el fichero project.properties  y descomentar la siguiente linea

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

Ojo, solo funcionará cuando hagamos la Exportación a APK, no cuando lo ejecutemos en emulador o el terminal directamente desde el Eclipse. Básicamente porque sería imposible usar el debug con el código ofuscado.
Sin embargo, no es todo tan bonito, los cambios de nombre tiene problemas

  • Si invocas clases o métodos de forma dinámica mediante el nombre, fallará, pues no se renombran.
  • Los Activitys fallarán al no estar contemplados en el Manifiest
  • Las referencias de R pueden provocar distintos errores
  • Los ENUMs parece que también dan algún problema que otro

¿Solución? Añadir excepciones para que ProGuard no modifique ciertos ficheros. En mi caso uso este que añade compatibilidad con ActionBarSherlock y Admob.


# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
#-dontoptimize
#-dontpreverify

# If you want to enable optimization, you should include the
# following:
 -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
 -optimizationpasses 5
-allowaccessmodification
#
# Note that you cannot just include these flags in your own
# configuration file; if you are including this file, optimization
# will be turned off. You'll need to either edit this file, or
# duplicate the contents of this file and remove the include of this
# file from your project's proguard.config path property.

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
 native <methods>;
}

-keep public class * extends android.view.View {
 public <init>(android.content.Context);
 public <init>(android.content.Context, android.util.AttributeSet);
 public <init>(android.content.Context, android.util.AttributeSet, int);
 public void set*(...);
}

-keepclasseswithmembers class * {
 public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
 public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
 public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
 public static **[] values();
 public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
 public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.R$* {
 public static <fields>;
}

-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
-dontwarn com.google.ads.**

Si haces “cosas raras” quizás tengas que adaptar la configuración según tus necesidades, lo cual no sería difícil siguiendo la configuración.

Finalmente, tenemos otro problema: Si nos mandan un reporte de un error, este estará ofuscado, mostrando los nombres de métodos y clases modificados, como “Null Pointer en a, en el método b, en la clase a del paquete a.a.c”, totalmente ilegible. ¿Solución? Hacer uso de las herramientas de ProGuard.

Al realizar la exportación nos aparecerá una carpeta llamada proguard donde contendrá varios archivos, entre ellos, el mapping.txt, el encargado de traducir el código.
Bastará con ir a la carpeta RUTA_SDK/tools/proguard/bin/ y ejecutar:  retrace -verbose mapping.txt TU_LOG.txt  y te mostrará la traducción.

Anuncios
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: