बिल्ड फ्लेवर्स का उपयोग करना - सोर्स फोल्डर्स का निर्माण और बिल्ड.ग्रेड सही ढंग से


166

कृपया ध्यान दें: जेवियर के उत्तर के बाद संपादित किया गया उत्तर

मैं एंड्रॉइड स्टूडियो में एक ही एप्लिकेशन प्रोजेक्ट के लिए विभिन्न बिल्ड फ्लेवर का उपयोग करने की कोशिश कर रहा हूं । हालांकि, मुझे लगता है कि यह उचित रूप से काम करने के लिए एक भयानक समय है।

कदम:

  1. एक नया एंड्रॉइड स्टूडियो प्रोजेक्ट बनाएं, जिसका नाम 'टेस्ट' है।
  2. Build.gradle * खोलें और निम्न पंक्तियाँ जोड़े:

    productFlavors {
    flavor1 {
        packageName 'com.android.studio.test.flavor1'
        }
    flavor2 {
        packageName 'com.android.studio.test.flavor2'
        }
    }
  3. एंड्रॉइड स्टूडियो को पुनरारंभ करने के बाद, अब मैं बिल्ड वेरिएंट अनुभाग के तहत 4 बिल्ड वेरिएंट देखता हूं । मतलब कि हम अभी तक उत्पाद के स्वादों को स्थापित करने में सफल थे। **
  4. स्वाद 1 के लिए एक नया स्रोत फ़ोल्डर बनाया गया ; हालाँकि, मुझे यकीन नहीं है कि मैं इसे सही तरीके से कर रहा हूँ। यहाँ है कि मैंने यह कैसे किया:

    • ध्यान रखें कि इस परियोजना के लिए मेरा पैकेज का नाम है: com.foo.test
    • srcस्वाद 1 के लिए फ़ोल्डर पर राइट क्लिक करें , मैंने वास्तव में एक्सप्लोरर को अलग-अलग फ़ोल्डर में बनाया है, इस तरह से कि संरचना है src/flavor1/java/com/foo/test/MainActivity.java
    • उपरोक्त अच्छी तरह से काम किया, क्योंकि 'जावा' फ़ोल्डर नीले रंग में है , जिसका अर्थ है कि आईडीई एक सक्रिय स्रोत निर्देशिका जानता है। इसके अलावा, पैकेज स्वचालित रूप से बनाया गया था। इसके बावजूद, मुझे डुप्लीकेट क्लास के लिए चेतावनी मिल रही है। यहां देखें स्क्रीनशॉट
    • स्वाद 2 के लिए, मैंने मैन्युअल रूप से पैकेज बनाने की कोशिश की, लेकिन स्वाद 2 के लिए 'src' फ़ोल्डर नीले रंग में नहीं है, और इसलिए जब राइट क्लिक किया जाता है तो विकल्प अलग होते हैं, और मेरे लिए 'नया पैकेज' उपयोग करने के लिए उपलब्ध नहीं होता है। यहां देखें छवि
    • ध्यान दें कि स्वाद 1 के लिए, मैंने एक 'रेस' निर्देशिका भी बनाई है, जो नीले रंग में बदल जाती है, लेकिन इसके बावजूद, मैं एंड्रॉइड रिसोर्स फ़ाइल या एंडरॉयड संसाधन निर्देशिका बनाने की क्षमता प्रदान नहीं करता, अगर मैं अलग उपयोग करना चाहता था विभिन्न जायके के लिए resoruces।

क्या मुझसे कुछ गलत हो रही है? या क्या मैं कुछ न कुछ भूल रहा हूं? मुझे बताएं यदि आपको अधिक जानकारी की जरूरत है।

* मेरी परियोजना के लिए दो build.gradle फ़ाइलें है लगता है । एक परियोजना फ़ोल्डर (\ GradleTest) की जड़ पर स्थित है, यह एक खाली है। दूसरा ग्रेड \ ग्रेडलेस्ट के सबफ़ोल्डर की जड़ पर स्थित है, जिसे 'ग्रेडलेस्ट' (ग्रेडलेस्ट-ग्रेडलेस्ट) भी कहा जाता है, यह वह है जिसमें पहले से ही कोड था जब खोला गया था; इसलिए, यह वह है जिसे मैंने संपादित किया है।

** मैंने ग्रेड सेटिंग्स की जाँच की और जाहिरा तौर पर ऑटो-आयात का उपयोग पहले से ही सक्षम था इसके बावजूद, बिल्ड.ग्रेड फ़ाइल में परिवर्तन करने से बिल्ड वेरिएंट स्वचालित रूप से अपडेट नहीं होता हैनोट: मैंने बिल्ड - पुनर्निर्माण प्रोजेक्ट, और / या बिल्ड - मेक प्रोजेक्ट, नो-गो का उपयोग करके भी कोशिश की। मुझे अभी भी परियोजना को बंद करना है, और परिवर्तनों को प्रभावी करने के लिए फिर से खोलना है।


ध्यान दें कि applicationIdअब इसके बजाय समर्थित है packageName
हमज़ेह सोबोह

जवाबों:


220

यदि आपको स्टूडियो वरीयताओं में मिला है, तो ग्रैडल अनुभाग के तहत, आप अपनी परियोजना के लिए ऑटो-आयात सक्षम कर सकते हैं (हम इसे डिफ़ॉल्ट रूप से बाद में सक्षम करेंगे)। जब भी आप इसे संपादित करते हैं, तो स्टूडियो आपके build.gradle को पुन: आयात करेगा।

स्वाद बनाने का मतलब यह नहीं है कि आप उनके लिए कस्टम कोड का उपयोग करने जा रहे हैं, इसलिए हम फ़ोल्डर नहीं बनाते हैं। आपको उन्हें स्वयं बनाने की आवश्यकता है।

यदि आप मेरी IO बात को देखते हैं, तो आप देखेंगे कि हम कैसे जायके से एक साथ मूल्यों में मिश्रण करते हैं और प्रकार बनाने के लिए बनाते हैं।

जावा स्रोत के लिए:

src/main/java
src/flavor1/java
src/debug/java

सभी 3 एकल आउटपुट बनाने के लिए उपयोग किए जाते हैं। इसका मतलब है कि वे एक ही वर्ग को परिभाषित नहीं कर सकते हैं।

यदि आप दो स्वादों में एक ही वर्ग का एक अलग संस्करण चाहते हैं, तो आपको इसे दोनों स्वादों में बनाना होगा।

src/flavor1/java/com/foo/A.java
src/flavor2/java/com/foo/A.java

और फिर src / main / java में आपका कोड कर सकते हैं

import com.foo.A

चयनित स्वाद के आधार पर, com.foo.A का सही संस्करण उपयोग किया जाता है।

इसका यह भी मतलब है कि ए के दोनों संस्करण में एक ही एपीआई होना चाहिए (कम से कम जब यह src / main / bava / ... में कक्षाओं द्वारा उपयोग किए जाने वाले API की बात आती है ...

संशोधित प्रश्न से मिलान करने के लिए संपादित करें

इसके अतिरिक्त, समान ए को केवल स्रोत फ़ोल्डर्स में एक ही वर्ग रखना महत्वपूर्ण है जो पारस्परिक रूप से अनन्य हैं। इस स्थिति में src / flavor1 / java और src / flavor2 / java को कभी एक साथ नहीं चुना जाता है, लेकिन मुख्य और flavor1 हैं।

यदि आप अलग-अलग स्वाद में एक गतिविधि का एक अलग संस्करण प्रदान करना चाहते हैं तो इसे src / main / java में न डालें।

ध्यान दें कि यदि आपके पास 3 स्वाद थे और केवल स्वाद 1 के लिए एक कस्टम चाहता था, जबकि स्वादिष्ट 2 और स्वाद 3 ने एक ही गतिविधि साझा की, तो आप उन दो अन्य गतिविधियों के लिए एक सामान्य स्रोत फ़ोल्डर बना सकते हैं। आपके पास नए स्रोत फ़ोल्डर बनाने और उन्हें उपयोग करने के लिए सेट किए गए स्रोत को कॉन्फ़िगर करने में कुल लचीलापन है।

आपके अन्य बिंदुओं पर:

यह सामान्य है कि 2 स्वाद स्रोत फ़ोल्डर नीला नहीं है। आपको इसे सक्षम करने के लिए 2 के स्वाद पर स्विच करने की आवश्यकता है, और फिर आप अंदर संकुल और कक्षाएं बना पाएंगे। तब तक, स्टूडियो इसे स्रोत फ़ोल्डर नहीं मानता है। हम उम्मीद है कि आईडीई उन के बारे में पता करने के लिए भविष्य में इस सुधार होगा unactive स्रोत फ़ोल्डर्स।

मुझे लगता है कि यह भी सामान्य है कि आप रिस फ़ोल्डर में संसाधन फ़ाइलें नहीं बना सकते। इन सभी अतिरिक्त संसाधन फ़ोल्डरों से निपटने के लिए मेनू सिस्टम अपडेट नहीं किया गया है। यह बाद में आएगा।


1
मैंने अपने उत्तर के अंत में कुछ नए तत्व जोड़े, लेकिन डुप्लिकेट समझ में आता है। आपके पास src / main / java और src / flavor1 / java दोनों में समान वर्ग नहीं हो सकता क्योंकि दोनों जब taste1 का चयन करते हैं तो दोनों का उपयोग किया जाता है। मेरे जवाब में, ध्यान दें कि मैंने एक ही क्लास को केवल फ्लेवर 1 / जावा और फ्लेवर 2 / जावा में कैसे डाला क्योंकि ये एक्सक्लूसिव हैं और कभी भी एक साथ सक्षम नहीं होते हैं।
जेवियर डुक्रोटेट

हे जेवियर, क्या आप मुझे इस बात का अधिक विस्तृत विवरण दे सकते हैं कि मैं अपने जायके में किसी गतिविधि के विभिन्न संस्करण का उपयोग कैसे कर सकता हूं? मेरे पास एक परीक्षण परियोजना है जहां मैं अपनी MainActivity के विभिन्न संस्करणों का उपयोग करना चाहता हूं, लेकिन दोनों एप्स (स्वाद 1 और स्वाद 2) में केवल मुख्य / जावा का संस्करण है। जब मैं MainActivity को मुख्य / जावा के अंदर नहीं डालता हूं, तो जब मैं इसे शुरू करता हूं तो ऐप क्रैश हो जाता है।
जेन्सजेन

@XavierDucrohet विभिन्न संसाधनों के साथ-साथ विभिन्न प्रकार के फ़्लेवर के आधार पर कोड कैसे बना सकता है, लेकिन उन्हें अलग-अलग मॉड्यूल में रखा है ताकि हम एक ही रूट प्रोजेक्ट में कोड और संसाधनों को मिलाए बिना स्वाद के आधार पर एक मॉड्यूल या दूसरे को शामिल कर सकें? क्या वह समर्थित है?
वेलेरियो शांतिनेली

3
@ValerioSantinelli आप प्रति-स्वाद निर्भरता कर सकते हैं। उपयोगflavorCompile ...
जेवियर डुक्रोटे

@XavierDucrohet मैंने वही सुझाया जो आपने सुझाया था लेकिन यह वैसा काम नहीं कर रहा है जैसा कि मुझे उम्मीद थी। आप देख सकते हैं कि कैसे मेरी परियोजना वहां संरचित है: stackoverflow.com/q/24410995/443136
वेलेरियो सेंटिनेली

19

Android पर "उत्पाद जायके"

मुझे कभी-कभी अलग-अलग मेजबानों, आइकन, या यहां तक ​​कि पैकेज नामों के साथ काम करने के लिए कहा जाता है, एक ही ऐप के विभिन्न संस्करणों पर लागू होते हैं।

ऐसा करने के लिए बहुत सारे कारण हैं और एक आसान तरीका है: उत्पाद जायके।

आप अपनी बिल्ड.gradle स्क्रिप्ट पर इस तरह की चीजों को परिभाषित कर सकते हैं जो मैंने पहले बताई हैं।

उत्पाद जायके इस लेख का हिस्सा उत्पाद के स्वादों पर सोचकर लिखा गया है, इसलिए, वे क्या हैं? Android प्रलेखन के बारे में:

एक उत्पाद स्वाद परियोजना द्वारा निर्मित एप्लिकेशन के एक अनुकूलित संस्करण को परिभाषित करता है। एक एकल परियोजना में अलग-अलग स्वाद हो सकते हैं जो उत्पन्न अनुप्रयोग को बदलते हैं।

आप उन्हें कैसे परिभाषित कर सकते हैं? आपको अपने build.gradle पर लिखना होगा जो फ्लेवर आप परिभाषित करना चाहते हैं:

productFlavors {  
        ...
        devel {
            ...
        }

        prod {
            ...
        }
    }

अब, हमारे पास हमारे ऐप के दो अलग-अलग फ्लेवर होंगे। आप इसे बिल्ड वेरिएंट टैब के अंदर एंड्रॉइड स्टूडियो पर भी देख सकते हैं

वेरिएंट बनाएँ

एकाधिक पैकेज नाम

क्या होगा यदि आप अपने फोन पर एक एप्लिकेशन डेवलपमेंट स्टेट के साथ और एक प्रोडक्शन स्टेट के लिए इंस्टॉल करना चाहते हैं। जैसा कि आप जानते हैं, आप केवल एक ऐप को एक ही पैकेज नाम के साथ इंस्टॉल कर सकते हैं (यदि आप अपने फोन पर इंस्टॉल किए गए कुछ नए एपीके को उसी के साथ इंस्टॉल करने का प्रयास करते हैं, तो वह इसे अपडेट करने का प्रयास करेगा)।

केवल एक चीज जो आपको करनी है, वह यह है कि आप अपने प्रत्येक उत्पाद के स्वाद पर इसे परिभाषित करें:

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
        }
        prod {
            applicationId "zuul.com.android"
        }
    }
}

स्वाद के आधार पर कई मेजबानों के लिए अनुरोध भेजें पहले की तरह, आपको अपने उत्पाद स्वाद विन्यास क्षेत्र पर कुछ पैरामेट्स को शामिल करना होगा।

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
            buildConfigField 'String', 'HOST', '"http://192.168.1.34:3000"'

        }

        prod {
            applicationId "zuul.com.android"
               buildConfigField 'String', 'HOST', '"http://api.zuul.com"'

        }
    }
}

एक उदाहरण के रूप में, हम आपको यह दिखाने की कोशिश करेंगे कि एपट्रप्ट सर्वर को अनुरोध भेजने के लिए आप रेट्रोफिट के साथ इसे कैसे एकीकृत कर सकते हैं, यह बताए बिना कि आप किस सर्वर को इंगित कर रहे हैं और स्वाद के आधार पर। इस मामले में यह ज़ूल एंड्रॉइड ऐप का एक अंश है:

public class RetrofitModule {

    public ZuulService getRestAdapter() {
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(BuildConfig.HOST)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        return restAdapter.create(ZuulService.class);
    }

}

जैसा कि आप देख सकते हैं कि आपको सिर्फ आपके द्वारा परिभाषित चर तक पहुंचने के लिए BuildConfigclass का उपयोग करना होगा।

आपके कोड के माध्यम से उपलब्ध कोई भी वैरिएबल HOST वैरिएबल एकमात्र नहीं है जिसे आप अपने कोड में उजागर कर सकते हैं। आप इसे जो चाहें उसके साथ कर सकते हैं:

prod {  
    applicationId "zuul.com.android"
    buildConfigField 'String', 'HOST', '"http://api.zuul.com"'
    buildConfigField 'String', 'FLAVOR', '"prod"'
    buildConfigField "boolean", "REPORT_CRASHES", "true"
}

आप उन्हें इस प्रकार एक्सेस कर सकते हैं:

BuildConfig.HOST  
BuildConfig.FLAVOR  
BuildConfig.REPORT_CRASHES  

स्वाद के अनुसार अलग-अलग चिह्न यदि आप स्वाद के अनुसार अलग-अलग चिह्न रखना चाहते हैं, तो आप नेत्रहीन रूप से यह पता लगा सकते हैं कि आप कौन सा खोल रहे हैं (आप इसे नाम से भी कर सकते हैं ... लेकिन यह अंतरिक्ष में फिट नहीं हो सकता है!), आपके पास बस है। प्रत्येक जायके के लिए नई निर्देशिका संरचनाओं को परिभाषित करना।

उदाहरण में, मैंने अभी उपयोग किया है दो फ्लेवर हैं: डेवेल और ठेस। फिर, हम दो नई निर्देशिका संरचनाओं को परिभाषित कर सकते हैं ताकि हम उन संसाधनों को परिभाषित कर सकें जो हम चाहते हैं:

संरचना

यह अन्य प्रकार के संसाधनों जैसे कि strings.xml, integers.xml, arrays.xml, आदि के साथ काम करता है ।

साइनिंग सेटिंग्स कॉन्फ़िगर करें

मैन्युअल रूप से अपनी रिलीज़ बिल्ड बिल्ड के लिए साइनिंग कॉन्फ़िगरेशन को कॉन्फ़िगर करें ग्रैड बिल्ड कॉन्फ़िगरेशन का उपयोग करके कॉन्फ़िगर करें:

1. एक कीस्टोरी बनाएं। कीस्टॉर एक बाइनरी फ़ाइल है जिसमें निजी कुंजी का एक सेट होता है। आपको अपने किस्टोर को सुरक्षित और सुरक्षित जगह पर रखना होगा। 2. एक निजी कुंजी बनाएँ। एक निजी कुंजी ऐप के साथ पहचानी जाने वाली इकाई का प्रतिनिधित्व करती है, जैसे कोई व्यक्ति या कंपनी। 3. मॉड्यूल-स्तर build.gradle फ़ाइल पर हस्ताक्षर करने के लिए जोड़ें:

android {
...
defaultConfig {...}
signingConfigs {
    release {
        storeFile file("myreleasekey.keystore")
        storePassword "password"
        keyAlias "MyReleaseKey"
        keyPassword "password"
    }
}
buildTypes {
    release {
        ...
        signingConfig signingConfigs.release
    }
}

}

एक हस्ताक्षरित APK उत्पन्न करें:

एक हस्ताक्षरित एपीके को जेनरेट करने के लिए, मुख्य मेनू से बिल्ड> जेनरेट साइनड एपीके का चयन करें। ऐप / बिल्ड / एपीके / ऐप-रिलीज़.पैक में पैकेज अब आपकी रिलीज़ कुंजी के साथ हस्ताक्षरित है।

रेफरी: https://developer.android.com/studio/build/viltants.html#signing,http://blog.brainattica.com/how-to-work-with-flavours-on-android/



7

ऐसा लगता है कि आपको नए स्वादों को जोड़ने के बाद अपनी परियोजना को फिर से लोड करने की आवश्यकता है build.gradle। उसके बाद, आपको बिल्ड वेरिएंट व्यू में 4 बिल्ड वेरिएंट दिखाई देंगे (आप इसे विंडो के बाएं किनारे से एक्सेस करते हैं)।

अतिरिक्त स्रोत निर्देशिकाओं के बारे में, ऐसा लगता है कि आपको उन्हें हाथ से बनाने की आवश्यकता है: src/flavor1/javaऔर src/flavor2/java। आप देखेंगे कि "बिल्ड वेरिएंट" दृश्य में स्वाद बदलने से वर्तमान में सक्रिय स्रोत निर्देशिकाएं बदल जाएंगी (जब यह एक सक्रिय स्रोत निर्देशिका है तो निर्देशिका नीली है )

अंत में, इसका मतलब है कि Gradle वस्तुओं का निर्माण करेगा "Gradle अपने नए जायके के लिए नए sourceSets पैदा करेगा" android.sourceSets.flavor1और android.sourceSets.flavor2और आप अपने build.gradle लिपि में उन्हें इस्तेमाल कर सकते हैं। लेकिन उन वस्तुओं को गतिशील रूप से बनाया जाता है, इसीलिए आप उन्हें नहीं देखते हैं build.gradle(मैं आपको यह पढ़ने का सुझाव देता हूं: http://www.gradle.org/docs/current/userguide/tutorial_using_tasks.html विशेष रूप से 6.6: यह समझाता है गत्यात्मक कार्य का निर्माण। एक ग्रन्थ लिपि एक ग्रूवी लिपि है, इसलिए मेरा सुझाव है कि आप ग्रूवी से भी परिचित हों)


2
मुझे लगता है कि आयात नोट Build Variantsदृश्य है, मैंने उस पर ध्यान नहीं दिया।
क्रिस। जेनकिंस

2

मेरे पास यही मुद्दा था जब मैंने अपनी परियोजना को ग्रैडल में स्थानांतरित कर दिया था। समस्या यह थी कि बिल्ड को उचित संसाधन फ़ोल्डर नहीं मिला। मैंने इसे build.gradle में android तत्व के तहत जोड़कर तय किया:

sourceSets {
        main {
            res.srcDirs = ['myProject/res']
        }
    }

0

कुछ ऐसा है जो महत्वपूर्ण है और मुझे काफी समय के लिए अवरुद्ध करता है, स्वाद नाम जिसे पैकेज से मेल खाने के लिए पैकेज का विरोध करने की आवश्यकता है, जो कि स्वाद की परिभाषा के अंदर वर्गीकृत है। उदाहरण के लिए:

src/flavor1/java/com/foo/A.java

मैच होगा

productFlavors {
  flavor1 {
    packageName 'com.android.studio.test.foobar'
  }
}

परंतु

src/foobar/java/com/foo/A.java स्वाद 1 के निर्माण के लिए उपयोग नहीं किया जाएगा।


0

श्रेणी में:

बिल्ड प्रकारों के लिए आपको केवल आवश्यकता है:

buildTypes {
   release{
    //proguard, signing etc.
   }
   debug {
    //development
   }
  }
}

और फिर स्वादों के लिए आप अपनी ज़रूरत के हिसाब से जोड़ते हैं

productFlavors {
    pro {
        applicationIdSuffix '.paid'
        buildConfigField 'boolean', 'PRO', 'true'
    }
    free {
        applicationIdSuffix '.free'
        buildConfigField 'boolean', 'PRO', 'false'
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.