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




gradle android-library (10)

एंड्रॉइड स्टूडियो 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

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

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

जब मैं डीबग मोड में अपना ऐप चलाता हूं तो 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 वैरिएबल का उपयोग करें जो एप्लिकेशन क्लास से पहले चलता है।


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

/**
 * 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");

मैंने इस समाधान को https://code.google.com/p/android/issues/detail?id=52962 पर भी साझा किया है।


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

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();

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

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

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

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

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

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


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

import io.fabric.sdk.android.BuildConfig;

इस मामले में BuildConfig.DEBUG हमेशा झूठी वापसी करेगा;

import com.yourpackagename.BuildConfig;

इस मामले में BuildConfig.DEBUG आपके वास्तविक निर्माण संस्करण को वापस कर देगा


आप परियोजनाओं में से प्रत्येक परियोजना पर कोशिश कर सकते हैं टाइप:

parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}

आप प्रत्येक बिल्ड प्रकार के लिए ग्रेडल का उपयोग करके अपनी खुद की 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!");

मेरे मामले में मैं गलत BuildConfig आयात कर रहा था क्योंकि मेरे प्रोजेक्ट में कई लाइब्रेरी मॉड्यूल हैं। फिक्स मेरे app मॉड्यूल के लिए सही BuildConfig आयात करना था।


हम भी यही समस्या थी। मैं इस तरह कुछ के साथ आया था:

हमारे पास एक एसडीके (लाइब्रेरी) और डेमो प्रोजेक्ट है, पदानुक्रम इस तरह दिखता है:

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

हमारे पास डेमो ऐप के लिए, थे :SDK:jarjarDebug और :SDK:jarjarRelease कुछ विशिष्ट कार्य हैं :SDK जो कुछ पोस्ट-प्रोसेस किए गए जार का उत्पादन करते हैं:

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

यह एक ही buildTypes निर्मित कई buildTypes लिए भी काम करता है। हालांकि डिबगिंग थोड़ा मुश्किल है। कृपया टिप्पणी करें।







android-library