BuildConfig.DEBUG no funciona (= lógicamente establecido en falso) cuando ejecuto mi aplicación en modo de depuración. Uso Gradle para construir. Tengo un proyecto de biblioteca donde hago esta verificación. BuildConfig.java se ve así en la carpeta de depuración de compilación:
/** Automatically generated the file. DO NOT MODIFY */
package common.myProject;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
}
y en la carpeta de lanzamiento:
public static final boolean DEBUG = false;
tanto en el proyecto de biblioteca como en el proyecto de aplicación.
Intenté solucionar esto comprobando una variable que se establece en una clase de mi proyecto. Esta clase hereda de la biblioteca y comienza al inicio.
<application
android:name=".MyPrj" ...
Esto conduce a otro problema: es que utilizo mi variable DEBUG en un DataBaseProvider que se ejecuta antes que la clase de aplicación y no se ejecutará correctamente debido a este error.
android
gradle
android-library
usuario1324936
fuente
fuente
Respuestas:
Este es el comportamiento esperado para esto.
Los proyectos de biblioteca solo publican sus variantes de lanzamiento para el consumo de otros proyectos o módulos.
Estamos trabajando para solucionar este problema, pero esto no es trivial y requiere una cantidad significativa de trabajo.
Puede rastrear el problema en https://code.google.com/p/android/issues/detail?id=52962
fuente
Con Android Studio 1.1 y teniendo también la versión de gradle en 1.1 es posible:
Biblioteca
android { publishNonDefault true }
Aplicación
dependencies { releaseCompile project(path: ':library', configuration: 'release') debugCompile project(path: ':library', configuration: 'debug') }
La documentación completa se puede encontrar aquí http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication
EDITAR :
El problema se acaba de marcar como solucionado para Android Studio Gradle versión 3.0. Allí solo puede usar
implementation project(path: ':library')
y seleccionará la configuración correcta automáticamente.fuente
Compruebe que
imports
, a veces, BuildConfig se importa de cualquier clase de biblioteca sin querer. Por ejemplo:import io.fabric.sdk.android.BuildConfig;
En este caso, BuildConfig.DEBUG siempre devolverá falso ;
import com.yourpackagename.BuildConfig;
En este caso, BuildConfig.DEBUG devolverá su variante de compilación real .
fuente
Esta es como la respuesta de Phil, excepto que no necesita el contexto:
private static Boolean sDebug; /** * Is {@link BuildConfig#DEBUG} still broken for library projects? If so, use this.</p> * * See: https://code.google.com/p/android/issues/detail?id=52962</p> * * @return {@code true} if this is a debug build, {@code false} if it is a production build. */ public static boolean isDebugBuild() { if (sDebug == null) { try { final Class<?> activityThread = Class.forName("android.app.ActivityThread"); final Method currentPackage = activityThread.getMethod("currentPackageName"); final String packageName = (String) currentPackage.invoke(null, (Object[]) null); final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig"); final Field DEBUG = buildConfig.getField("DEBUG"); DEBUG.setAccessible(true); sDebug = DEBUG.getBoolean(null); } catch (final Throwable t) { final String message = t.getMessage(); if (message != null && message.contains("BuildConfig")) { // Proguard obfuscated build. Most likely a production build. sDebug = false; } else { sDebug = BuildConfig.DEBUG; } } } return sDebug; }
fuente
Como solución alternativa, puede utilizar este método, que utiliza la reflexión para obtener el valor del campo de la aplicación (no de la biblioteca):
/** * Gets a field from the project's BuildConfig. This is useful when, for example, flavors * are used at the project level to set custom fields. * @param context Used to find the correct file * @param fieldName The name of the field-to-access * @return The value of the field, or {@code null} if the field is not found. */ public static Object getBuildConfigValue(Context context, String fieldName) { try { Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig"); Field field = clazz.getField(fieldName); return field.get(null); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; }
Para obtener el
DEBUG
campo, por ejemplo, simplemente llame a esto desde suActivity
:boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
También he compartido esta solución en AOSP Issue Tracker .
fuente
applicationIdSuffix
en Gradle que haría que la.BuildConfig
clase no sea accesible desde este código anterior.No es realmente la forma correcta de verificar si está en versión de depuración, pero puede verificar si la aplicación en sí es depurable a través de:
private static Boolean sIsDebuggable; public static boolean isDebuggable(Context context) { if (sIsDebuggable == null) sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; return sIsDebuggable; }
El comportamiento predeterminado de las aplicaciones y bibliotecas coincidirá perfectamente con él.
Si necesita una solución alternativa mejor, puede usar esto en su lugar:
public static boolean isInDebugFlavour(Context context) { if (sDebugFlavour == null) { try { final String packageName = context.getPackageName(); final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig"); final Field DEBUG = buildConfig.getField("DEBUG"); DEBUG.setAccessible(true); sDebugFlavour = DEBUG.getBoolean(null); } catch (final Throwable t) { sDebugFlavour = false; } } return sDebugFlavour; }
fuente
Puede crear su propia clase BuildConfig para cada tipo de compilación usando gradle
public class MyBuildConfig { public static final boolean DEBUG = true; }
para /src/debug/.../MyBuildConfig.java y ...
public class MyBuildConfig { public static final boolean DEBUG = false; }
para /src/release/.../MyBuildConfig.java
Entonces usa:
if (MyBuildConfig.DEBUG) Log.d(TAG, "Hey! This is debug version!");
fuente
Aquí hay otra solución.
1) Crea una interfaz
public interface BuildVariantDetector { boolean isDebugVariant(); }
2) Utilice esta interfaz en la clase de aplicación (módulo de aplicación)
public class MyApplication extends Application implements BuildVariantDetector { @Override public boolean isDebugVariant() { return BuildConfig.DEBUG; //application (main module) Buildonfig } }
3) Y luego en el módulo de biblioteca:
boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();
fuente
Tuvimos el mismo problema. Se me ocurrió algo como esto:
Tenemos un SDK (biblioteca) y un proyecto de demostración, la jerarquía se ve así:
Parent | + SDK (:SDK) | + DemoApp (:DemoApp)
Para la aplicación de demostración tenemos, fueron
:SDK:jarjarDebug
y:SDK:jarjarRelease
son algunas tareas específicas para las:SDK
que producen algunos frascos posprocesados:dependencies { debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files ... more dependencies ... }
Esto funciona incluso para varios
buildTypes
construidos a la vez. Sin embargo, la depuración es un poco difícil. Por favor comenta.fuente
Esta es mi solución: refleje BuildConfig del módulo de la aplicación:
`public static boolean debug = isDebug ();
private static boolean isDebug() { boolean result = false; try { Class c = Class.forName("com.example.app.BuildConfig"); Field f = c.getField("DEBUG"); f.setAccessible(true); result = f.getBoolean(c); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return result; }`
fuente
Puedes probar esto en cada uno de los proyectos buildTypes:
parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}
fuente
buildType
configuración de compilación y no a la de la compilación. La configuración teórica de la firma de depuración debería hacer el mismo trucoEn mi caso, estaba importando mal
BuildConfig
ya que mi proyecto tiene muchos módulos de biblioteca. La solución fue importar la correctaBuildConfig
para miapp
módulo.fuente
Trabajando con verdadero depurable en archivo gradle.
buildTypes { demo{ debuggable true } live{ debuggable true } }
fuente
BuildConfig.DEBUG no es confiable en absoluto, Android ha proporcionado una marca interna que está disponible globalmente que indica si una compilación está en modo Debug o no Debug
(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)
será cierto si está en depuración
Créditos: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120
fuente