9

मैं एंड्रॉइड स्टूडियो (वी 2.1, ग्रेडल प्लगइन वी 2.1.0) का उपयोग कर एक एंड्रॉइड एप्लिकेशन विकसित कर रहा हूं। मेरे एप्लिकेशन में कई संस्करण हैं जो बहुत सारे सामान्य कोड साझा करते हैं, इसलिए मैंने अनुरोध किए जाने पर कोड और संसाधनों को अनुकूलित करने के लिए स्वाद आयामों और उत्पाद स्वादों का उपयोग करने का निर्णय लिया। यह तब तक जुर्माना लगा जब तक कि मेरे पास केवल दो स्वाद आयाम थे। उदाहरण के लिए, मेरी app.gradleएंड्रॉइड स्टूडियो: दो स्वाद आयामों (स्वाद समूह) के साथ उत्पाद स्वाद संयोजन

… 
flavorDimensions "fruit", "color" 

productFlavors { 

    apple { 
     dimension "fruit" 
    } 
    pear { 
     dimension "fruit" 
    } 

    red { 
     dimension "color" 
    } 
    yellow { 
     dimension "color" 
    } 
} 
… 

और मेरे src फ़ोल्डर

src/ 
    appleRed/ 
    appleYellow/ 
    pearRed/ 
    pearYellow/ 

मेरी कोड के एक कस्टम संस्करण के साथ हर एक था। फिर, एक उदाहरण

src/ 
    appleRed/java/com/example/ExampleFragment.java 
    appleYellow/java/com/example/ExampleFragment.java 
    pearRed/java/com/example/ExampleFragment.java 
    pearYellow/java/com/example/ExampleFragment.java 
निश्चित रूप से

के रूप में, वहाँ src/main में ExampleFragment का कोई उदाहरण नहीं है।

विकास के दौरान कुछ बिंदु पर, मैं एक मुक्त शामिल करने के लिए किया था और एक अनुप्रयोग के संस्करण का भुगतान किया। मैंने सोचा था कि यह आसानी से एक नया स्वाद आयाम version और दो उत्पाद free और paid नामित जायके नामित जोड़कर प्राप्त किया जा सकता:

… 
flavorDimensions "fruit", "color”, “version” 

productFlavors { 

    apple { 
     dimension "fruit" 
    } 
    pear { 
     dimension "fruit" 
    } 

    red { 
     dimension "color" 
    } 
    yellow { 
     dimension "color" 
    } 

    free { 
     dimension "version" 
    } 
    paid { 
     dimension “version” 
    } 
} 
… 

लेकिन की fruit और color नहीं था संयोजन द्वारा उत्पन्न अचानक कस्टम कोड के सभी एंड्रॉइड स्टूडियो द्वारा अब पता चला है।

src/ 
     appleRedFree/java/com/example/ExampleFragment.java 
     appleRedPaid/java/com/example/ExampleFragment.java 
     appleYellowFree/java/com/example/ExampleFragment.java 
     appleYellowPaid/java/com/example/ExampleFragment.java 
     pearRedFree/java/com/example/ExampleFragment.java 
     pearRedPaid/java/com/example/ExampleFragment.java 
     pearYellowFree/java/com/example/ExampleFragment.java 
     pearYellowPaid/java/com/example/ExampleFragment.java 

यह नहीं है: तो कोई appleRed, appleYellow, pearRed और न ही pearYellow कस्टम कोड और एक ही रास्ता मैं अपने विन्यास हासिल करने में सक्षम था के लिए इस्तेमाल किया जा सकता तीनों स्वाद आयाम के सभी संयोजनों का उपयोग किया गया अच्छा क्योंकि ExampleFragment उसी fruitColor* संयोजन (appleRedFree, appleRedPaid में डुप्लीकेट किया गया है, उसी ExampleFragment) है। संसाधनों के लिए एक ही समस्या होती है (res फ़ोल्डर में से)।

मेरे प्रश्न हैं:

1) एंड्रॉयड स्टूडियो (यानी में Gradle से अपेक्षित व्यवहार, उनके आयाम के आधार पर उत्पाद जायके का एक सबसेट गठबंधन करने के लिए, उनकी प्राथमिकता निम्नलिखित में सक्षम नहीं होने, जब चल रहा है दो से अधिक स्वाद आयाम)?

2) तथ्य यह है कि यह अपेक्षित व्यवहार है, वहाँ एक और तरीका है मैं डुप्लिकेट किए गए कोड के बिना या एक अगर बयान अंदर (जैसे, if (BuildConfig.FLAVOR_version == "free") ...) के साथ एक एकल फाइल बिना मेरी अनुकूलन को प्राप्त कर सकते है को देखते हुए?

कृपया ध्यान दें कि मैं कस्टम कोड होने के बारे में बात कर रहा हूं जो जटिल हो सकता है, इसलिए मैं मूल कॉन्फ़िगरेशन चर, वैरिएंट फ़िल्टरिंग, या ऐसा कुछ जैसे मूल अनुकूलन के लिए नहीं कह रहा हूं।

उत्तर

6

आप कुछ स्वादों के लिए एक ही अतिरिक्त स्रोत निर्देशिका का उपयोग करना चाहते हैं;

appleRedFree + appleRedPaid --> src/appleRed
pearRedFree + pearRedPaid --> src/pearRed
appleYellowFree + appleYellowPaid --> src/appleYellow
pearYellowFree + pearYellowPaid --> src/pearYellow

आप सेट कर सकते sourceSet अपने जायके के लिए:

android { 

    // Other stuff here 

    flavorDimensions "fruit", "color”, “version” 

    productFlavors { 

     apple { 
      dimension "fruit" 
     } 
     pear { 
      dimension "fruit" 
     } 

     red { 
      dimension "color" 
     } 
     yellow { 
      dimension "color" 
     } 

     free { 
      dimension "version" 
     } 
     paid { 
      dimension “version” 
     } 
    } 

    sourceSets { 
     appleRedFree { 
      java.srcDirs = ['src/main/java', 'src/appleRed/java'] 
     } 

     appleRedPaid { 
      java.srcDirs = ['src/main/java', 'src/appleRed/java'] 
     } 

     appleYellowFree { 
      java.srcDirs = ['src/main/java', 'src/appleYellow/java'] 
     } 

     appleYellowPaid { 
      java.srcDirs = ['src/main/java', 'src/appleYellow/java'] 
     } 

     pearRedFree { 
      java.srcDirs = ['src/main/java', 'src/pearRed/java'] 
     } 

     pearRedPaid { 
      java.srcDirs = ['src/main/java', 'src/pearRed/java'] 
     } 

     pearYellowFree { 
      java.srcDirs = ['src/main/java', 'src/pearYellow/java'] 
     } 

     pearRedPaid { 
      java.srcDirs = ['src/main/java', 'src/pearYellow/java'] 
     } 
    } 

    // Other stuff here 
} 
+0

काम नहीं करता। ग्रैडल प्रोजेक्ट सिंक त्रुटि के साथ विफल रहता है: 'त्रुटि: (46, 0) एंड्रॉइडसोर्ससेट कंटेनर पर तर्क [build_5p3mtjx0cpg9la7ms46x7bgzz $ _run_closure2 $ _closure8 @ 5d22a1be] के लिए विधि appleRedFree() विधि नहीं मिल सका। क्या आप कहीं भी' लागू प्लगइन 'शामिल करना भूल गए हैं? – Vangaorth

+1

@Vangaorth मैंने अपना जवाब अपडेट कर दिया है। – Devrim

+0

अब यह काम करता है! आपको नवीनतम (लेखन के समय) ग्रैडल एंड्रॉइड प्लगइन (2.3.0) और ग्रैडल (3.3) का भी उपयोग करना होगा। तो, एंड्रॉइड स्टूडियो में, फ़ाइल -> प्रोजेक्ट स्ट्रक्चर -> प्रोजेक्ट टैब, ग्रैडल वर्जन 3.3 और एंड्रॉइड प्लगइन संस्करण 2.3.0 – Vangaorth

संबंधित मुद्दे