BuildConfig.DEBUG ne fonctionne pas (= la valeur logique est définie sur false) lorsque j'exécute mon application en mode débogage . J'utilise Gradle pour créer. J'ai un projet de bibliothèque où je fais cette vérification. BuildConfig.Java ressemble à ceci dans le dossier de débogage de la construction:
/** Automatically generated the file. DO NOT MODIFY */
package common.myProject;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
}
et dans le dossier de publication:
public static final boolean DEBUG = false;
à la fois dans le projet de bibliothèque et dans le projet d'application.
J'ai essayé de contourner cela en vérifiant une variable qui est définie dans une classe de mon projet. Cette classe hérite de la bibliothèque et démarre au démarrage.
<application
Android:name=".MyPrj" ...
Cela pose un autre problème: c’est que j’utilise ma variable DEBUG dans un DataBaseProvider qui s’exécute avant la classe d’application, et elle ne fonctionnera pas correctement en raison de ce bogue.
C'est le comportement attendu pour cela.
Les projets de bibliothèque publient uniquement leurs variantes de version pour être utilisés par d'autres projets ou modules.
Nous travaillons à la résolution de ce problème, mais ce n’est pas anodin et demande beaucoup de travail.
Vous pouvez suivre le problème à l’adresse https://code.google.com/p/Android/issues/detail?id=52962
Avec Android Studio 1.1 et ayant également la version graduée à 1.1, il est possible:
Bibliothèque
Android {
publishNonDefault true
}
App
dependencies {
releaseCompile project(path: ':library', configuration: 'release')
debugCompile project(path: ':library', configuration: 'debug')
}
Une documentation complète est disponible ici http://tools.Android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication
MODIFIER:
Le problème vient d'être marqué comme résolu pour Android Studio Gradle Version 3.0. Là, vous pouvez simplement utiliser implementation project(path: ':library')
et cela sélectionnera automatiquement la configuration correcte.
Recherchez imports
, parfois BuildConfig est importé de toute classe de bibliothèque par inadvertance . Par exemple:
import io.fabric.sdk.Android.BuildConfig;
Dans ce cas BuildConfig.DEBUG retournera toujours false ;
import com.yourpackagename.BuildConfig;
Dans ce cas, BuildConfig.DEBUG renverra votre variante réelle build.
C'est comme la réponse de Phil, sauf qu'elle n'a pas besoin du contexte:
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;
}
Pour contourner le problème, vous pouvez utiliser cette méthode, qui utilise la réflexion pour obtenir la valeur de champ de l'application (et non de la bibliothèque):
/**
* 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;
}
Pour obtenir le champ DEBUG
, par exemple, appelez simplement ceci à partir de votre Activity
:
boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
J'ai également partagé cette solution sur AOSP Issue Tracker .
Ce n'est pas vraiment la bonne façon de vérifier si vous êtes dans le style de débogage, mais vous pouvez vérifier si l'application elle-même est débogable via:
private static Boolean sIsDebuggable;
public static boolean isDebuggable(Context context) {
if (sIsDebuggable == null)
sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
return sIsDebuggable;
}
Le comportement par défaut des applications et des bibliothèques correspondra parfaitement.
Si vous avez besoin d'une meilleure solution de contournement, vous pouvez utiliser ceci à la place:
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;
}
Voici une autre solution.
1) Créer une interface
public interface BuildVariantDetector {
boolean isDebugVariant();
}
2) Utiliser cette interface sur la classe d’application (module d’application)
public class MyApplication extends Application implements BuildVariantDetector {
@Override
public boolean isDebugVariant() {
return BuildConfig.DEBUG; //application (main module) Buildonfig
}
}
3) Et ensuite dans le module de bibliothèque:
boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();
Vous pouvez créer votre propre classe BuildConfig pour chaque type de construction en utilisant gradle
public class MyBuildConfig
{
public static final boolean DEBUG = true;
}
pour /src/debug/.../MyBuildConfig.Java and ...
public class MyBuildConfig
{
public static final boolean DEBUG = false;
}
pour /src/release/.../MyBuildConfig.Java
Alors utilisez:
if (MyBuildConfig.DEBUG)
Log.d(TAG, "Hey! This is debug version!");
Voici ma solution de contournement: Reflète BuildConfig du module d'application:
`public statique 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;
}`
Nous avons eu le même problème. Je suis venu avec quelque chose comme ça:
Nous avons un SDK (bibliothèque) et un projet de démonstration, la hiérarchie ressemble à ceci:
Parent
|
+ SDK (:SDK)
|
+ DemoApp (:DemoApp)
:SDK:jarjarDebug
et :SDK:jarjarRelease
sont des tâches spécifiques à :SDK
qui produisent des fichiers jar post-traités:
dependencies {
debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files
releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files
... more dependencies ...
}
Cela fonctionne même pour plusieurs buildTypes
construits à la fois. Le débogage est un peu difficile cependant. Commentez s'il vous plaît.
Travailler avec debuggable true dans le fichier Gradle.
buildTypes {
demo{
debuggable true
}
live{
debuggable true
}
}
BuildConfig.DEBUG n'est pas du tout fiable, Android a fourni un indicateur interne globalement disponible indiquant si une génération est en mode débogage ou non.
(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)
sera vrai s'il est en débogage
Crédits: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da109812
Vous pouvez essayer ceci sur chacun des projets buildTypes:
parent.allprojects.each{ project -> Android.defaultConfig.debuggable = true}
Dans mon cas, j'importais la mauvaise BuildConfig
car mon projet comporte de nombreux modules de bibliothèque. Le correctif consistait à importer la BuildConfig
correcte pour mon module app
.