Según Google, debo " desactivar las llamadas a los métodos de registro en el código fuente " antes de publicar mi aplicación de Android en Google Play. Extracto de la sección 3 de la lista de verificación de publicación :
Asegúrese de desactivar el registro y deshabilitar la opción de depuración antes de compilar su aplicación para su lanzamiento. Puede desactivar el registro eliminando llamadas a los métodos de registro en sus archivos de origen.
Mi proyecto de código abierto es grande y es difícil hacerlo manualmente cada vez que lo lanzo. Además, eliminar una línea de registro es potencialmente complicado, por ejemplo:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
Si comento la línea de registro, la condición se aplica a la siguiente línea y es probable que no se llame a load (). ¿Son tales situaciones tan raras que puedo decidir que no debería existir?
Entonces, ¿hay una mejor manera de hacerlo a nivel de código fuente? ¿O tal vez una sintaxis inteligente de ProGuard para eliminar de manera eficiente pero segura todas las líneas de registro?
fuente
sed 's_^\(\s*Log\.\)_;//'`date|tr -s \ -`'\1_g'
en su lugar.Respuestas:
Creo que una solución mucho más fácil es olvidar todos los
if
controles por todas partes y simplemente usar ProGuard para eliminar cualquier llamadaLog.d()
oLog.v()
método cuando llamamos a nuestrorelease
objetivo Ant .De esa manera, siempre tenemos la información de depuración que se genera para las compilaciones regulares y no tenemos que hacer ningún cambio de código para las compilaciones de lanzamiento. ProGuard también puede hacer múltiples pases sobre el código de bytes para eliminar otras declaraciones no deseadas, bloques vacíos y puede incorporar automáticamente métodos cortos cuando sea apropiado.
Por ejemplo, aquí hay una configuración ProGuard muy básica para Android:
Así que guardaría eso en un archivo, luego llamaría a ProGuard desde Ant, pasando su JAR recién compilado y el JAR de la plataforma Android que está utilizando.
Vea también los ejemplos en el manual de ProGuard.
Actualización (4,5 años después): hoy en día utilizo Timber para el registro de Android.
No solo es un poco mejor que la
Log
implementación predeterminada : la etiqueta de registro se configura automáticamente y es fácil registrar cadenas formadas y excepciones, sino que también puede especificar diferentes comportamientos de registro en tiempo de ejecución.En este ejemplo, las declaraciones de registro solo se escribirán en logcat en las versiones de depuración de mi aplicación:
La madera está configurada en mi
Application
onCreate()
método:Luego, en cualquier otro lugar de mi código, puedo iniciar sesión fácilmente:
Consulte la aplicación de ejemplo Timber para ver un ejemplo más avanzado, donde todas las declaraciones de registro se envían a logcat durante el desarrollo y, en producción, no se registran declaraciones de depuración, pero los errores se informan silenciosamente a Crashlytics.
fuente
Todas son buenas respuestas, pero cuando terminé con mi desarrollo, no quería usar declaraciones if en todas las llamadas de Log, ni quería usar herramientas externas.
Entonces, la solución que estoy usando es reemplazar la clase android.util.Log con mi propia clase Log:
Lo único que tenía que hacer en todos los archivos fuente era reemplazar la importación de android.util.Log con mi propia clase.
fuente
Log.d("tag", someValue.toString());
, es muy fácil olvidarse de comprobar algún valor por no ser nulo, lo que significa que podría arrojar unNullPointerException
producto en producción. Sugiere una solución segura pero te engañará. Nosprivate static boolean DEBUG
if(DEBUG)Log.d(TAG, msg);
String
. La solución completa se describe aquí . Aparentemente, esto tiene otro inconveniente: cada llamada debe editarse (no solo una línea de importación).static final boolean LOG = BuildConfig.DEBUG
y no tener que modificar este archivo nunca.Sugiero tener un booleano estático en algún lugar que indique si iniciar sesión o no:
Luego, donde quiera iniciar sesión en su código, simplemente haga esto:
Ahora, cuando configura MyDebug.LOG en falso, el compilador eliminará todo el código dentro de tales comprobaciones (dado que es un final estático, sabe en tiempo de compilación que el código no se usa).
Para proyectos más grandes, es posible que desee comenzar a tener booleanos en archivos individuales para poder habilitar o deshabilitar fácilmente el registro allí según sea necesario. Por ejemplo, estas son las diferentes constantes de registro que tenemos en el administrador de ventanas:
Con el código correspondiente como:
fuente
La solución Proguard de Christopher es la mejor, pero si por alguna razón no le gusta Proguard, aquí hay una solución de muy baja tecnología:
Registros de comentarios:
Registros sin comentar:
Una restricción es que sus instrucciones de registro no deben abarcar varias líneas.
(Ejecute estas líneas en un shell de UNIX en la raíz de su proyecto. Si usa Windows, obtenga una capa UNIX o use comandos equivalentes de Windows)
fuente
//
vs.;//
)Me gustaría agregar algunas precisiones sobre el uso de Proguard con Android Studio y gradle, ya que tuve muchos problemas para eliminar las líneas de registro del binario final.
Para poder hacer
assumenosideeffects
trabajos en Proguard, hay un requisito previo.En su archivo gradle, debe especificar el uso del
proguard-android-optimize.txt
archivo predeterminado.En realidad, en el
proguard-android.txt
archivo predeterminado , la optimización está deshabilitada con las dos banderas:El
proguard-android-optimize.txt
archivo no agrega esas líneas, por lo que ahoraassumenosideeffects
puede funcionar.Luego, personalmente, uso SLF4J , aún más cuando desarrollo algunas bibliotecas que se distribuyen a otras. La ventaja es que por defecto no hay salida. Y si el integrador quiere algunas salidas de registro, puede usar Logback para Android y activar los registros, por lo que los registros se pueden redirigir a un archivo o a LogCat.
Si realmente necesito quitar los registros de la biblioteca final, entonces agrego a mi archivo Proguard (después de haber habilitado el
proguard-android-optimize.txt
archivo, por supuesto):fuente
proguard-android-optimize.txt
archivo Proguard predeterminado como el archivo-assumenosideeffects
Proguard personalizado! Estoy usando R8 shinker (el valor predeterminado hoy en día) y el registro predeterminado de Android.Recomiendo usar Timber de Jake Wharton
https://github.com/JakeWharton/timber
resuelve su problema con habilitar / deshabilitar además agrega clase de etiqueta automáticamente
sólo
los registros solo se usarán en la versión de depuración y luego se usarán
o
imprimir
"Tu clase / mensaje" sin especificar la etiqueta
fuente
He usado una clase LogUtils como en la aplicación de ejemplo Google IO. Modifiqué esto para usar una constante DEBUG específica de la aplicación en lugar de BuildConfig.DEBUG porque BuildConfig.DEBUG no es confiable . Luego en mis clases tengo lo siguiente.
fuente
Build.DEBUG
que solía usar. También me di por vencido con las diversas soluciones "correctas" y utilicé una solución de estilo similar para usted.Consideraría usar la función de registro de roboguice en lugar del android.util.Log incorporado
Su instalación deshabilita automáticamente la depuración y los registros detallados para las versiones de lanzamiento. Además, obtienes algunas funciones ingeniosas de forma gratuita (por ejemplo, comportamiento de registro personalizable, datos adicionales para cada registro y más)
Usar proguard podría ser bastante complicado y no tendría problemas para configurarlo y hacerlo funcionar con su aplicación a menos que tenga una buena razón para eso (deshabilitar los registros no es bueno)
fuente
Estoy publicando esta solución que se aplica específicamente para usuarios de Android Studio. También descubrí recientemente Timber y lo importé con éxito en mi aplicación haciendo lo siguiente:
Ponga la última versión de la biblioteca en su build.gradle:
Luego, en Android Studios, vaya a Editar -> Buscar -> Reemplazar en ruta ...
Escriba
Log.e(TAG,
o, sin embargo, haya definido sus mensajes de registro en el"Text to find"
cuadro de texto. Entonces solo lo reemplazas conTimber.e(
Haga clic en Buscar y luego reemplace todo.
Android Studios ahora revisará todos sus archivos en su proyecto y reemplazará todos los registros con Timbers.
El único problema que tuve con este método es que gradle aparece con un millón de mensajes de error después porque no puede encontrar "Madera" en las importaciones para cada uno de sus archivos java. Simplemente haga clic en los errores y Android Studios importará automáticamente "Timber" a su Java. Una vez que lo haya hecho para todos sus archivos de errores, Gradle compilará nuevamente.
También debe poner este código en el
onCreate
método de suApplication
clase:Esto dará como resultado el registro de la aplicación solo cuando esté en modo de desarrollo y no en producción. También puede tener
BuildConfig.RELEASE
para iniciar sesión en modo de lanzamiento.fuente
import android\.util\.Log\;
Reemplace con:import android\.util\.Log\;\nimport timber\.log\.Timber\;
Por android.util.Log proporciona una forma de habilitar / deshabilitar el registro:
Por defecto, el método isLoggable (...) devuelve falso, solo después de configurar la aplicación en el dispositivo le gusta esto:
Significa que se puede imprimir cualquier registro por encima del nivel DEBUG. Documento de Android de referencia:
Entonces podríamos usar la utilidad de registro personalizada:
fuente
Si puede ejecutar un reemplazo global (una vez), y luego preservar una convención de codificación, puede seguir el patrón que se usa a menudo en el marco de Android .
En lugar de escribir
tenerlo como
Ahora proguard puede eliminar StringBuilder y todas las cadenas y métodos que utiliza en el camino, desde la versión optimizada DEX. Use
proguard-android-optimize.txt
y no necesita preocuparse por android.util. Inicie sesión enproguard-rules.pro
:Con el complemento Gradle de Android Studio, es bastante confiable, por lo que no necesita constantes adicionales para controlar la eliminación.
BuildConfig.DEBUG
fuente
Agregue seguimiento a su archivo proguard-rules.txt
fuente
Esto es lo que solía hacer en mis proyectos de Android ...
En Android Studio, podemos hacer una operación similar, Ctrl + Shift + F para buscar desde todo el proyecto (Comando + Shift + F en MacOs) y Ctrl + Shift + R para Reemplazar ((Comando + Shift + R en MacOs))
fuente
Tengo una solución muy simple. Utilizo IntelliJ para el desarrollo, por lo que los detalles varían, pero la idea debería aplicarse en todos los IDE.
Elijo la raíz de mi árbol de origen, hago clic derecho y selecciono "reemplazar". Luego elijo reemplazar todo "Registro". con "// Registro". Esto elimina todas las declaraciones de registro. Para volver a colocarlos más tarde, repito el mismo reemplazo, pero esta vez como reemplazar todos los "// Registro". con "Registro".
Funciona muy bien para mí. Solo recuerde configurar el reemplazo como mayúsculas y minúsculas para evitar accidentes como "Diálogo". Para mayor seguridad, también puede hacer el primer paso con "Registro". como la cadena para buscar.
Brillante.
fuente
Como sugirió el comentario de zserge ,
su biblioteca de registro proporciona un interruptor de activación / desactivación de impresión de registros simple como se muestra a continuación.
Además, solo requiere cambiar las
import
líneas, y nada necesita cambiar para laLog.d(...);
declaración.fuente
He mejorado la solución anterior al proporcionar soporte para diferentes niveles de registro y al cambiar los niveles de registro automáticamente dependiendo de si el código se ejecuta en un dispositivo en vivo o en el emulador.
fuente
ProGuard lo hará por usted en su versión de lanzamiento y ahora las buenas noticias de android.com:
http://developer.android.com/tools/help/proguard.html
La herramienta ProGuard reduce, optimiza y ofusca su código al eliminar el código no utilizado y renombrar clases, campos y métodos con nombres semánticamente oscuros. El resultado es un archivo .apk de menor tamaño que es más difícil de realizar ingeniería inversa. Debido a que ProGuard hace que su aplicación sea más difícil de aplicar ingeniería inversa, es importante que la use cuando su aplicación utilice características sensibles a la seguridad, como cuando está otorgando licencias a sus aplicaciones.
ProGuard está integrado en el sistema de compilación de Android, por lo que no tiene que invocarlo manualmente. ProGuard solo se ejecuta cuando compila su aplicación en modo de lanzamiento, por lo que no tiene que lidiar con el código ofuscado cuando construye su aplicación en modo de depuración. Hacer que ProGuard se ejecute es completamente opcional, pero muy recomendable.
Este documento describe cómo habilitar y configurar ProGuard, así como utilizar la herramienta de retroceso para decodificar trazas de pila ofuscadas
fuente
Me gusta usar Log.d (TAG, alguna cadena, a menudo un String.format ()).
TAG es siempre el nombre de la clase
Transform Log.d (TAG, -> Logd (en el texto de su clase
De esta manera, cuando esté listo para hacer una versión de lanzamiento, configure MainClass.debug en falso.
fuente
Los registros se pueden eliminar usando bash en linux y sed:
Funciona para registros multilínea. En esta solución puede estar seguro de que los registros no están presentes en el código de producción.
fuente
Sé que esta es una vieja pregunta, pero ¿por qué no reemplazaste todas tus llamadas de registro con algo como Boolean logCallWasHere = true; // --- resto de tu registro aquí
Es por eso que sabrá cuándo desea volver a colocarlos, y no afectarán su llamada de declaración if :)
fuente
¿Por qué no solo hacer
? No se necesitan bibliotecas adicionales, no hay reglas de protección que tienden a arruinar el proyecto y el compilador de Java simplemente omitirá el código de bytes para esta llamada cuando realice la compilación de lanzamiento.
fuente
Log.d("tag","msg");
, y también es fácil olvidar escribir laif(BuildConfig.DEBUG)
parte.Aquí está mi solución si no desea meterse con bibliotecas adicionales o editar su código manualmente. He creado este portátil Jupyter para repasar todos los archivos java y comentar todos los mensajes de registro. No es perfecto, pero hizo el trabajo por mí.
fuente
mi manera:
1) habilitar el modo de selección de columna (alt + shift + insert)
2) seleccione en un Log.d (TAG, "texto"); la parte 'Registro'.
3) luego haz shift + ctrl + alt + j
4) haz clic en la flecha izquierda
5) hacer shift + end
6) presiona eliminar.
esto elimina todas las llamadas de LOG a la vez en un archivo java.
fuente
Puede intentar usar este sencillo método convencional:
Ctrl+ Shift+R
reemplazar
Con
fuente
Fácil con kotlin, solo declara algunas funciones de nivel superior
fuente
la forma más simple
utilizar
DebugLog
DebugLog desactiva todos los registros cuando se lanza la aplicación.
https://github.com/MustafaFerhan/DebugLog
fuente