सवाल Gradele के साथ लाइब्रेरी परियोजनाओं का निर्माण करते समय BuildConfig.DEBUG हमेशा झूठी


जब मैं डीबग मोड में अपना ऐप चलाता हूं तो BuildConfig.DEBUG काम नहीं कर रहा है (= तार्किक रूप से गलत पर सेट है)। मैं निर्माण के लिए ग्रेडल का उपयोग करता हूं। मेरे पास एक लाइब्रेरी प्रोजेक्ट है जहां मैं यह चेक करता हूं। BuildConfig.java बिल्ड डीबग फ़ोल्डर में ऐसा दिखता है:

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

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

}

और रिलीज फ़ोल्डर में:

public static final boolean DEBUG = false;

लाइब्रेरी प्रोजेक्ट और एप्लिकेशन प्रोजेक्ट में दोनों।

मैंने एक वैरिएबल की जांच करके इसे पाने की कोशिश की जो मेरी परियोजना का एक वर्ग निर्धारित करता है। यह वर्ग लाइब्रेरी से विरासत में आता है और स्टार्टअप पर शुरू होता है।

<application
        android:name=".MyPrj" ...

इससे एक और समस्या आई: डेटाबेजप्रोवाइडर में मेरे DEBUG वैरिएबल का उपयोग करें जो एप्लिकेशन क्लास से पहले चलता है।


76
2017-11-24 15:29


मूल


यह एक सामान्य व्यवहार है। मुद्दा कहां है? आपको BuildVariants के बीच स्विच करना होगा - Gabriele Mariotti
BuildConfig फ़ाइल सही ढंग से जेनरेट की जाती है लेकिन रन टाइम पर यह गलत है। मुझे भी वही समस्या हो रही है। - jophde


जवाब:


इसके लिए व्यवहार की उम्मीद है।

पुस्तकालय परियोजनाएं अन्य परियोजनाओं या मॉड्यूल द्वारा खपत के लिए केवल अपने रिलीज वेरिएंट प्रकाशित करती हैं।

हम इसे ठीक करने पर काम कर रहे हैं लेकिन यह गैर तुच्छ है और काम की एक बड़ी मात्रा की आवश्यकता है।

आप इस मुद्दे को ट्रैक कर सकते हैं https://code.google.com/p/android/issues/detail?id=52962


50
2017-12-16 18:18



वर्कअराउंड: BuildConfig.DEBUG के इंस्टेड ने lib-project के उदाहरण पर एक और बूलियन वैरिएबल बनाया है। BuildConfig.RELEASE और इसे एप्लिकेशन के buildType से लिंक करें। विवरण: gist.github.com/almozavr/d59e770d2a6386061fcb - Aleksey Malevaniy
समस्या ट्रैकर में डोडोइन्टे द्वारा प्रदान किया गया समाधान ठीक काम करता है, काम के आसपास की आवश्यकता नहीं है। - 3c71
अब यह मामला नहीं है। इसके लिए एक उचित समाधान है। देख मेरा जवाब अधिक जानकारी के लिए। - Niklas
यह सच है लेकिन इसे मैन्युअल रूप से किया जाना है, और स्वाद के साथ बहुत अच्छी तरह से स्केल नहीं करता है। हम भविष्य में इसे और अधिक स्वचालित बनाना चाहते हैं। - Xavier Ducrohet
@XavierDucrohet यह एक अप्रत्याशित और काउंटर अंतर्ज्ञानी व्यवहार है। यदि आप कर सकते हैं तो आपको निश्चित रूप से इसे ठीक करने का प्रयास करना चाहिए। - Radu


एंड्रॉइड स्टूडियो 1.1 के साथ और 1.1 पर भी ग्रेड संस्करण है यह संभव है:

पुस्तकालय

android {
    publishNonDefault true
}

ऐप

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

पूरा दस्तावेज यहां पाया जा सकता है http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

संपादित करें:

मुद्दा एंड्रॉइड स्टूडियो ग्रैडल संस्करण 3.0 के लिए अभी तय किया गया है। वहां आप बस उपयोग कर सकते हैं implementation project(path: ':library') और यह स्वचालित रूप से सही कॉन्फ़िगरेशन का चयन करेगा।


85
2018-03-20 09:32



इस तरह काम करता है। लेकिन एक कमी है: "लाइब्रेरी: इकट्ठा रिलीज" को आप के माध्यम से भी कहा जाता है ": ऐप: इकट्ठा डेबग", और इसके परिणामस्वरूप लंबे समय तक इमारत का समय लगेगा। - Alan Zhiliang Feng
वाह, उन्होंने आखिरकार उस पृष्ठ को अपडेट किया थोड़ा सा और अंततः उन्होंने इस सुविधा को जोड़ा। - Jared Burrows
धन्यवाद, यह काम किया! - Aykut Çevik
उत्कृष्ट समाधान, स्वीकृत उत्तर होना चाहिए। - natanavra
स्वच्छ समाधान और महान काम करता है। - FMontano


के लिए जाँचे imports, कभी कभी BuildConfig अनजाने में पुस्तकालय के किसी भी वर्ग से आयात किया जाता है। उदाहरण के लिए:

import io.fabric.sdk.android.BuildConfig;

इस मामले में BuildConfig.DEBUG हमेशा वापस आ जाएगा असत्य;

import com.yourpackagename.BuildConfig;

इस मामले में BuildConfig.DEBUG आपका असली वापस आ जाएगा संस्करण बनाओ।


37
2017-07-14 11:49



यह मेरे साथ मामला था। - Subin Sebastian
@ सुबिन सेबेस्टियन मुझे भी। - user1510006
जीवन बचतकर्ता, धन्यवाद ... - Arif Nadeem


यह फिल के जवाब की तरह है सिवाय इसके कि इसे संदर्भ की आवश्यकता नहीं है:

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

7
2018-02-03 02:55



इसके अनुसार (blog.javia.org/static-the-android-application-package) ब्लॉग पोस्ट आपको गतिविधि थ्रेड (यूआई थ्रेड) के अलावा किसी भी थ्रेड से currentPackageName विधि को कभी भी कॉल नहीं करना चाहिए। हालांकि कूल समाधान। - Rolf ツ
@Rolf ツ ठीक है आप इसके बजाय एप्लिकेशन-संदर्भ का उपयोग कर सकते हैं। - android developer


एक कामकाज के रूप में, आप इस विधि का उपयोग कर सकते हैं, जो ऐप से फ़ील्ड मान प्राप्त करने के लिए प्रतिबिंब का उपयोग करता है (लाइब्रेरी नहीं):

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

पाने के लिए DEBUG फ़ील्ड, उदाहरण के लिए, बस इसे अपने से कॉल करें Activity:

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

मैंने इस समाधान को भी साझा किया है एओएसपी अंक ट्रैकर


6
2017-08-27 01:41



यह कामकाज मुझे देता है StackOverflowError... - shkschneider
@shkschneider क्या लाइन? क्या आप अपना अपवाद पोस्ट कर सकते हैं? - Phil
दूसरों के लिए उपयोगी हो सकता है: के उपयोग से सावधान रहें applicationIdSuffix Gradle में जो बनाना होगा .BuildConfig कक्षा इस उपरोक्त कोड से पहुंच योग्य नहीं है। - shkschneider


यह जांचने का सही तरीका नहीं है कि आप डीबग स्वाद में हैं या नहीं, लेकिन आप यह जांच सकते हैं कि ऐप स्वयं डिबग करने योग्य है या नहीं:

private static Boolean sIsDebuggable;

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

ऐप्स और पुस्तकालयों का डिफ़ॉल्ट व्यवहार इसे पूरी तरह मेल करेगा।

यदि आपको बेहतर कामकाज की आवश्यकता है, तो आप इसके बजाय इसका उपयोग कर सकते हैं:

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
2018-06-21 09:51





आप प्रत्येक बिल्ड प्रकार के लिए ग्रेडल का उपयोग करके अपनी खुद की BuildConfig क्लास बना सकते हैं

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

के लिये /src/debug/.../MyBuildConfig.java तथा...

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

के लिये /src/release/.../MyBuildConfig.java

फिर उपयोग करें:

if (MyBuildConfig.DEBUG)
    Log.d(TAG, "Hey! This is debug version!");

2
2017-10-19 15:08



क्या पैकेज के लिए "..." पुस्तकालय का नाम है? यदि ऐसा है, तो यह काम नहीं कर रहा है। मैं कक्षा तक नहीं पहुंच सकता। - android developer


यहाँ एक और समाधान है।

1) एक इंटरफेस बनाएँ

public interface BuildVariantDetector {

    boolean isDebugVariant();

}

2) इस वर्ग का उपयोग अनुप्रयोग वर्ग (अनुप्रयोग मॉड्यूल) पर करें

public class MyApplication extends Application implements BuildVariantDetector {

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

}

3) और फिर लाइब्रेरी मॉड्यूल में:

boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();

2
2018-05-06 12:59



यह काम नहीं करता है। BuildConfig.DEBUG अभी भी मेरे लिए झूठा है। - DiscDev
सरल और सुरुचिपूर्ण समाधान। बस सुनिश्चित करें कि आप ऐप मॉड्यूल के BuildConfig को लाइब्रेरी नहीं आयात करते हैं। यह एक बहुत चुस्त गलती है। - WindRider