BuildConfig.DEBUG nie działa (= logicznie ustawiony na false), gdy uruchamiam aplikację w trybie debugowania. Używam Gradle do budowania. Mam projekt biblioteki, w którym robię to sprawdzenie. BuildConfig.java wygląda następująco w folderze debugowania kompilacji:
/** Automatically generated the file. DO NOT MODIFY */
package common.myProject;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
}
aw folderze wydania:
public static final boolean DEBUG = false;
zarówno w projekcie biblioteki, jak iw projekcie aplikacji.
Próbowałem to obejść, sprawdzając zmienną, która jest ustawiona na klasę mojego projektu. Ta klasa dziedziczy z biblioteki i jest uruchamiana podczas uruchamiania.
<application
android:name=".MyPrj" ...
Prowadzi to do innego problemu: używam mojej zmiennej DEBUG w DataBaseProvider, która działa przed klasą aplikacji i nie będzie działać poprawnie z powodu tego błędu.
android
gradle
android-library
user1324936
źródło
źródło
Odpowiedzi:
Jest to oczekiwane zachowanie w tym przypadku.
Projekty biblioteczne publikują tylko warianty wydania do wykorzystania przez inne projekty lub moduły.
Pracujemy nad rozwiązaniem tego problemu, ale nie jest to trywialne i wymaga znacznego nakładu pracy.
Możesz śledzić ten problem na https://code.google.com/p/android/issues/detail?id=52962
źródło
Dzięki Android Studio 1.1 i mając również wersję Gradle w wersji 1.1 jest możliwe:
Biblioteka
android { publishNonDefault true }
Aplikacja
dependencies { releaseCompile project(path: ':library', configuration: 'release') debugCompile project(path: ':library', configuration: 'debug') }
Pełną dokumentację można znaleźć tutaj http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication
EDYCJA :
Problem właśnie został oznaczony jako stałe dla Androida Studio Gradle wersji 3.0. Tam możesz po prostu użyć,
implementation project(path: ':library')
a automatycznie wybierze prawidłową konfigurację.źródło
Sprawdź
imports
, czy czasami BuildConfig jest importowany z dowolnej klasy biblioteki. Na przykład:import io.fabric.sdk.android.BuildConfig;
W tym przypadku BuildConfig.DEBUG zawsze zwróci false ;
import com.yourpackagename.BuildConfig;
W tym przypadku BuildConfig.DEBUG zwróci Twój prawdziwy wariant kompilacji.
źródło
To jest jak odpowiedź Phila, ale nie potrzebuje kontekstu:
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; }
źródło
Aby obejść ten problem, możesz użyć tej metody, która używa odbicia w celu pobrania wartości pola z aplikacji (nie z biblioteki):
/** * 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; }
Aby uzyskać
DEBUG
przykład, pole, po prostu zadzwoń do niego ze swojegoActivity
:boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");
Udostępniłem również to rozwiązanie w narzędziu do śledzenia problemów AOSP .
źródło
applicationIdSuffix
w Gradle, które spowodowałoby, że.BuildConfig
klasa nie byłaby dostępna z powyższego kodu.Nie jest to właściwy sposób sprawdzenia, czy jesteś w fazie debugowania, ale możesz sprawdzić, czy sama aplikacja jest debugowalna przez:
private static Boolean sIsDebuggable; public static boolean isDebuggable(Context context) { if (sIsDebuggable == null) sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; return sIsDebuggable; }
Domyślne zachowanie aplikacji i bibliotek będzie idealnie do niego pasować.
Jeśli potrzebujesz lepszego obejścia, możesz użyć tego:
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; }
źródło
Możesz utworzyć własną klasę BuildConfig dla każdego typu kompilacji za pomocą gradle
public class MyBuildConfig { public static final boolean DEBUG = true; }
dla /src/debug/.../MyBuildConfig.java i ...
public class MyBuildConfig { public static final boolean DEBUG = false; }
for /src/release/.../MyBuildConfig.java
Następnie użyj:
if (MyBuildConfig.DEBUG) Log.d(TAG, "Hey! This is debug version!");
źródło
Oto inne rozwiązanie.
1) Utwórz interfejs
public interface BuildVariantDetector { boolean isDebugVariant(); }
2) Użyj tego interfejsu w klasie aplikacji (moduł aplikacji)
public class MyApplication extends Application implements BuildVariantDetector { @Override public boolean isDebugVariant() { return BuildConfig.DEBUG; //application (main module) Buildonfig } }
3) A następnie w module biblioteki:
boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();
źródło
Mieliśmy ten sam problem. Wymyśliłem coś takiego:
Mamy SDK (bibliotekę) i projekt demonstracyjny, hierarchia wygląda tak:
Parent | + SDK (:SDK) | + DemoApp (:DemoApp)
W przypadku aplikacji demonstracyjnej mamy, byliśmy
:SDK:jarjarDebug
i mamy:SDK:jarjarRelease
kilka konkretnych zadań do:SDK
produkcji niektórych słoików po przetworzeniu:dependencies { debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files ... more dependencies ... }
Działa to nawet w przypadku wielu
buildTypes
budowanych jednocześnie. Debugowanie jest jednak nieco trudne. Proszę skomentuj.źródło
To jest moje obejście: odzwierciedlenie BuildConfig modułu aplikacji:
`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; }`
źródło
Możesz wypróbować to na każdym z projektów buildTypes:
parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}
źródło
buildType
a nie do konfiguracji kompilacji. Teoretycznie ustawienie podpisywania debugowania powinno zrobić tę samą sztuczkęW moim przypadku źle importowałem,
BuildConfig
ponieważ mój projekt ma wiele modułów bibliotecznych. Poprawka polegała na zaimportowaniu poprawnegoBuildConfig
dla mojegoapp
modułu.źródło
Praca z debugowalnym true w pliku gradle.
buildTypes { demo{ debuggable true } live{ debuggable true } }
źródło
BuildConfig.DEBUG nie jest w ogóle niezawodny, system Android dostarczył wewnętrzną flagę, która jest globalnie dostępna, wskazując, czy kompilacja jest w trybie debugowania, czy innym
(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)
będzie prawdziwe, jeśli jest w trakcie debugowania
Kredyty: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120
źródło