BuildConfig.DEBUG gradusli kutubxona loyihalarini yaratishda doimo noto'g'ri

Debug rejimida mening ilovamni ishlatganda BuildConfig.DEBUG ishlamayapti (= mantiqiy ravishda FALSE o'rnatilgan). Men qurish uchun gradusdan foydalanaman. Men bu tekshirishni amalga oshiradigan kutubxona loyiham bor. BuildConfig.java bu kabi tuzilgan disk raskadagi papkaga o'xshaydi:

/** Automatically generated file. DO NOT MODIFY */
package common.myProject;

public final class BuildConfig {
    public static final boolean DEBUG = Boolean.parseBoolean("true");

}

va chiqarilish papkasida:

public static final boolean DEBUG = false;

ham kutubxona loyihalarida, ham dasturda.

Men bu loyihani sinchkovlik bilan o'rnatgan o'zgaruvchichni tekshirib, bu haqda ma'lumot olishga harakat qildim. Bu sinf kutubxonadan meros bo'lib o'tadi va ishga tushiriladi.

Bu boshqa muammolarga olib keldi: dastur sinfidan oldin ishlaydigan DataBaseProviderda mening DEBUG o'zgaruvchimdan foydalanish.

76
Bu oddiy holat. Muammo qaerda? BuildVariants o'rtasida almashishingiz kerak
qo'shib qo'ydi muallif Gabriele Mariotti, manba
BuildConfig fayli to'g'ri ishlab chiqarilgan, ammo ishga tushirish vaqtida u noto'g'ri. Xuddi shu masala bilan shug'ullanaman.
qo'shib qo'ydi muallif jophde, manba

12 javoblar

Android Studio 1.1 bilan va 1.1 gradusli versiyasiga ega bo'lish mumkin:

Kutubxona

android {
    publishNonDefault true
}

Ilova

dependencies {
    releaseCompile project(path: ':library', configuration: 'release')
    debugCompile project(path: ':library', configuration: 'debug')
}

Complete documentation can be found here http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

EDIT:

chiqishi faqat Android Studio Gradle Version 3.0 uchun belgilangan deb belgilandi. U erda siz faqat dastur loyihasini (yo'l: ': library') dan foydalanishingiz mumkin va u to'g'ri konfiguratsiyani avtomatik ravishda tanlaydi.

85
qo'shib qo'ydi
Biz foydalanadigan har bir kutubxona uchun "App" qismini qo'shishimiz kerakmi? Agar shunday bo'lsa, bu juda zerikarli ...
qo'shib qo'ydi muallif android developer, manba
Rahmat, bu ishni amalga oshirdi!
qo'shib qo'ydi muallif Aykut Çevik, manba
Vau, ular nihoyat ushbu sahifani biroz yangilab chiqdilar va nihoyat ushbu funksiyani qo'shdilar.
qo'shib qo'ydi muallif Jared Burrows, manba
Shu tarzda ishlaydi. Biroq, ":": "kutubxona: assembleRelease" deb ataladi. "App: assembleDebug" ni yaratasiz va bu uzoq vaqt qurilish vaqtiga olib keladi.
qo'shib qo'ydi muallif Alan Zhiliang Feng, manba
Toza yechim va ajoyib ish.
qo'shib qo'ydi muallif FMontano, manba
@Konica Longer Gradle vaqtini qurish uchun pul to'lashning kichkina narxidir - bu konvolyutsiyaga va yana uzoq vaqtga boradi! Bu ajoyib ishladi! Barakalla!
qo'shib qo'ydi muallif Radu, manba
Yaxshi echim, ammo Android Studio'da "bekor qilish va qayta boshlash" tugmasini bosganimda menga xato ko'rsatiladi: Xato: Modul: kutubxonada "variant" versiyasi tanlangan, ammo modul "": app "moduli" .
qo'shib qo'ydi muallif anber, manba
Bu aniq va aniq javob bo'lishi kerak;) sehrli bu yerda shukur aytadi
qo'shib qo'ydi muallif Santi Iglesias, manba
Zo'r hal, qabul qilingan javob bo'lishi kerak.
qo'shib qo'ydi muallif natanavra, manba

Buning uchun kutilgan xatti-harakatlar.

Kutubxona loyihalari faqatgina boshqa loyihalar yoki modullar bilan iste'mol qilish uchun ularning ozod variantlarini nashr etadi.

Buni tuzatishga harakat qilmoqdamiz, ammo bu juda ahamiyatli emas va juda ko'p ishni talab qiladi.

You can track the issue at https://code.google.com/p/android/issues/detail?id=52962

50
qo'shib qo'ydi
Bu erda nima kutish mumkin? Loyiha o'zida bo'lgan kutubxonalar uchun yuz beradi, shuning uchun butun loyihani disk raskadrovka rejimida ishga tushirganimda nima uchun bu to'g'ri bo'lmasligi mumkin ...
qo'shib qo'ydi muallif android developer, manba
Bu endi ish emas. Buning uchun to'g'ri echim bor. Qo'shimcha ma'lumot uchun mening javobim -ga qarang.
qo'shib qo'ydi muallif Niklas, manba
@XavierDucrohet Bu kutilmagan va qarshi sezgir xatti. Agar imkon bo'lsa, uni tuzatishga harakat qilishingiz kerak.
qo'shib qo'ydi muallif Radu, manba
Bu to'g'ri, lekin uni qo'lda qilish kerak, va lazzat bilan juda yaxshi tarozida yo'q. Kelajakda uni yanada avtomatlashtirmoqchimiz.
qo'shib qo'ydi muallif Xavier Ducrohet, manba
DodoEnte tomonidan taqdim etiladigan hal qilishni kuzatuvchi ishni yaxshi bajaradi, ish joyiga ehtiyoj yo'q.
qo'shib qo'ydi muallif 3c71, manba
Vaqtinchalik echim: BuildConfig.DEBUG ning o'rnatilishi lib-loyihada, masalan, boshqa bir boolean o'zgaruvchini yaratadi. BuildConfig.RELEASE va ilovaning buildType bilan bog'lash. Tafsilotlar: gist.github.com/almozavr/d59e770d2a6386061fcb
qo'shib qo'ydi muallif Aleksey Malevaniy, manba

Ba'zan BuildConfig kutubxonaning har qanday sinfidan bevosita import qilinadigan imports ni tekshiring. Misol uchun:

import io.fabric.sdk.android.BuildConfig;

Bunday holda BuildConfig.DEBUG doimo noto'g'ri qaytadi;

import com.yourpackagename.BuildConfig;

In this case BuildConfig.DEBUG will return your real build variant.

37
qo'shib qo'ydi
Menga shunday bo'ldi.
qo'shib qo'ydi muallif Subin Sebastian, manba
Hayotni qutqaruvchi, rahmat ...
qo'shib qo'ydi muallif Arif Nadeem, manba
@SubinSebastian men ham.
qo'shib qo'ydi muallif user1510006, manba

Bu, Philning javobiga o'xshaydi, ammo u kontekstga muhtoj emas:

private static Boolean sDebug;

/**
 * Is {@link BuildConfig#DEBUG} still broken for library projects? If so, use this.

* * See: https://code.google.com/p/android/issues/detail?id=52962

* * @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; }
7
qo'shib qo'ydi
@Rolf tsu Siz buning o'rniga dastur kontekstidan foydalanishingiz mumkin.
qo'shib qo'ydi muallif android developer, manba
Bunga ko'ra ( blog.javia.org/static-the-android-application -paket ) blog post hech qachon mavjud thread (UI thread) tashqari biron-bir zarrachacha currentPackageName usuli chaqirmaslik kerak. Qattiq sovutgich.
qo'shib qo'ydi muallif Rolf ツ, manba

Vaqtinchalik echim sifatida siz ushbu usuldan foydalanishingiz mumkin. Bu usul maydondan ilovani (kutubxona emas) olish uchun aks ettiradi:

/**
 * 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;
}

Masalan, DEBUG maydonini olish uchun Activity dan uni chaqiring:

boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");

Men ushbu echimni AOSP Issue reytingi ga ulashdim.

6
qo'shib qo'ydi
@shkschneider nima? Siz istisno yozishingiz mumkinmi?
qo'shib qo'ydi muallif Phil, manba
Boshqalarga foydali bo'lishi mumkin: Gradle da applicationIdSuffix dan foydalanishdan ehtiyot bo'ling, bu .BuildConfig sinfini yuqoridagi koddan olish mumkin emas.
qo'shib qo'ydi muallif shkschneider, manba
Ushbu vaqtinchalik echim menga StackOverflowError ni beradi ...
qo'shib qo'ydi muallif shkschneider, manba

Haqiqatdan ham disk ruxsatsizligida tekshirishning to'g'ri usuli emas, lekin ilovaning o'zi orqali disk raskadroviy tekshiruvini tekshirishingiz mumkin:

private static Boolean sIsDebuggable;

public static boolean isDebuggable(Context context) {
    if (sIsDebuggable == null)
        sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    return sIsDebuggable;
}

Ilovalar va kutubxonalarning odatiy xatti-harakati unga mos keladi.

Yaxshi vaqtinchalik echim kerak bo'lsa, buning o'rniga uni ishlatishingiz mumkin:

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;
}
3
qo'shib qo'ydi

Mana bir yechim.

1) interfeys yarating

public interface BuildVariantDetector {

    boolean isDebugVariant();

}

2) Ushbu interfeysni Application sinfida (Appplication module)

public class MyApplication extends Application implements BuildVariantDetector {

    @Override
    public boolean isDebugVariant() {
        return BuildConfig.DEBUG; //application (main module) Buildonfig
    }

}

3) Keyin kutubxona modulida:

boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();
2
qo'shib qo'ydi
Oddiy va oqilona yechim. Faqat, ilova modulining BuildConfig-ni kutubxona emas, balki import qiling. Bu juda yovuz xato.
qo'shib qo'ydi muallif WindRider, manba
Bu ishlamayapti. BuildConfig.DEBUG men uchun hali ham yolg'ondir.
qo'shib qo'ydi muallif DiscDev, manba

Grader yordamida har bir qurilish turi uchun o'z BuildConfig sinfi yaratishingiz mumkin

public class MyBuildConfig
{
    public static final boolean DEBUG = true;
}

/src/debug /.../ MyBuildConfig.java va ...

public class MyBuildConfig
{
    public static final boolean DEBUG = false;
}

for /src/release/.../MyBuildConfig.java

So'ngra:

if (MyBuildConfig.DEBUG)
    Log.d(TAG, "Hey! This is debug version!");
2
qo'shib qo'ydi
Kutubxonaning packName uchun "..." bormi? Agar shunday bo'lsa, bu ish ko'rinmaydi. Sinfga kira olmayapman.
qo'shib qo'ydi muallif android developer, manba

Xuddi shu muammo bor edi. Men shunday bir narsa bilan keldim:

Bizda SDK (kutubxona) va demo loyihasi bor, ierarxiya quyidagicha ko'rinadi:

Parent
  |
  + SDK (:SDK)
  |
  + DemoApp (:DemoApp)

Demo ilovasi uchun : SDK: jarjarDebug va : SDK: jarjarRelease - ba'zi bir keyingi postlar yaratish uchun : SDK qayta ishlangan kavanozlar:

dependencies {
    debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files
    releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files
    ... more dependencies ...
}

Bu bir vaqtning o'zida bir necha marta tuzilgan buildTypes uchun ham ishlaydi. Ayni paytda disk raskadrovka biroz qiyin. Iltimos, sharh bering.

1
qo'shib qo'ydi

Mening loyihamda BuildConfig kodini import qildim, chunki loyihamda ko'p kutubxona modullari mavjud. Tuzatish BuildConfig kodini mening ilovasi moduli uchun import qilish edi.

0
qo'shib qo'ydi

Buni buildTypes loyihalarining har birida ko'rishingiz mumkin:

parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}
0
qo'shib qo'ydi
Iltimos, izohlab bera olasizmi? "Debug" buildType-ga qo'shingmi? Va har bir modul uchun? Xato: (31, 0) Bunday xususiyat yo'q: class uchun disk raskadrovli: com.android.build.gradle.internal.dsl.ProductFlavor_Decorate & zwnj; d
qo'shib qo'ydi muallif android developer, manba
Buni tekshirib, javobni yangilab olasizmi? Agar oson echim topilsa, men buni bilmoqchiman.
qo'shib qo'ydi muallif android developer, manba
Android grader plaginining xususiyatlari o'zgarib ketdi, shuning uchun bu endi haqiqiy emas. Debuggable bayroq tuzilgan konfiguratsiya emas, balki buildType ga ko'chirildi. Debugni imzolashni sozlash nazariyasi xuddi shu hiyla ishlatishi kerak
qo'shib qo'ydi muallif pablisco, manba

Bu mening vaqtinchalik halim: App modulining BuildConfig-ni aks ettirish:

`Public static boolean debug = ishDebug ();

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;
}`
0
qo'shib qo'ydi