unity tutorial studio minifyenabled features android proguard

android - tutorial - proguard unity



La eliminación del registro con ProGuard no elimina las cadenas que se están registrando (2)

Proguard tampoco me funciona, y no me gusta crear una envoltura alrededor de Log, por lo que he probado las siguientes soluciones:

Solución de trabajo

final static boolean IsDebugging = false;

y en su código:

if(IsDebugging) Log.i(TAG, "Debugging");

considere que debe usar la palabra clave final para que IsDebugging se convierta en verdadero o falso en el momento de la compilación y las cadenas de registro no aparezcan en el código de bytes final.

NO TRABAJANDO (IsDebugMode)

public static boolean IsDebugMode(Context context) { PackageManager pm = context.getPackageManager(); PackageInfo pi; try { pi = pm.getPackageInfo(context.getPackageName(),0); } catch (NameNotFoundException e) { return false; } return (pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; }

y en mi código:

boolean IsDebugging = Utils.IsDebugMode(this); if(IsDebugging) Log.i(TAG, "Debugging");

La solución anterior no imprime ningún Logcat en Logcat, pero la cadena de log se compila y existe en el bytecode final, que es malo.

La otra solución fue:

NO FUNCIONA (BuildConfid.DEBUG)

if(BuildConfig.DEBUG) Log.i(TAG, "Debugging");

Esto es lo mismo que la solución IsDebugMode. No imprime nada, pero las cadenas están en el bytecode final. Malo otra vez

Posible duplicado:
Eliminación de cadenas no utilizadas durante la optimización de ProGuard

Tengo una aplicación para Android con docenas de declaraciones de registro. Preferiría que no aparecieran en la versión de lanzamiento, así que usé Proguard con algo como esto en el archivo proguard.cfg :

-assumenosideeffects class android.util.Log { public static *** d(...); }

Pero el problema es que hay una gran cantidad de Log.d("something is " + something) , y aunque la declaración Log.d() se está eliminando del Log.d() , las cadenas aún están allí .

Entonces, siguiendo this respuesta, creé una clase envoltura simple, algo así como:

public class MyLogger { public static void d(Object... msgs) { StringBuilder log = new StringBuilder(); for(Object msg : msgs) { log.append(msg.toString()); } Log.d(TAG, log.toString()); } }

Luego proguard.cfg mi proguard.cfg :

-assumenosideeffects class my.package.MyLogger { public static *** d(...); }

¡Pero las cadenas aún se encuentran en el bytecode generado!

Aparte de esto, estoy usando el proguard.cfg estándar proporcionado por el SDK de Android. ¿Estoy haciendo algo mal?

Edit : después de examinar el código de bytes generado, vi que las cadenas estaban allí, pero no se estaban uniendo entre sí, como pensé. Estaban siendo almacenados en una matriz . ¿Por qué? Pasarlos como parámetros variables a mi método. Parece que a ProGuard no le gusta eso, así que modifiqué mi clase de registrador así:

public static void d(Object a) { log(a); } public static void d(Object a, Object b) { log(a, b); } (... I had to put like seven d() methods ...) private static void log(Object... msgs) { (same as before) }

Es feo, pero ahora las cadenas no están en ninguna parte en el bytecode.

¿Es este un tipo de error / limitación de ProGuard? ¿O es solo que no entiendo cómo funciona?


Su solución con diferentes métodos para diferentes números de argumentos es probablemente la más conveniente. Un método único con un número variable de argumentos sería mejor, pero la versión actual de ProGuard no es lo suficientemente inteligente como para eliminar todo el código no utilizado.

El compilador de java compila un número variable de argumentos como un argumento de una sola matriz. En el lado de la invocación, esto significa crear una matriz del tamaño correcto, rellenar los elementos y pasarla al método. ProGuard ve que la matriz se está creando y luego se utiliza para almacenar elementos en ella. No se da cuenta (aún) de que no se usa para operaciones útiles reales, con la invocación del método desaparecida. Como resultado, la creación e inicialización de la matriz se conservan.

Es una buena práctica verificar el código procesado si está esperando alguna optimización en particular.