एंड्रॉइड ग्रैडल में मल्टी फ्लेवर लाइब्रेरी पर आधारित मल्टी फ्लेवर ऐप


102

मेरे ऐप में कई बाजारों के लिए ऐप-बिलिंग सिस्टम के कई फ़्लेवर हैं।

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

सवाल यह है कि क्या एंड्रॉइड लाइब्रेरी में उत्पाद फ्लेवर हो सकता है?

यदि हां, तो मैं ऐप के संबंधित स्वाद में विभिन्न स्वादों को कैसे शामिल कर सकता हूं?

मैंने बहुत खोज की, और मुझे इस परिदृश्य के बारे में कुछ नहीं मिला। केवल एक ही करीबी चीज़ जो मुझे मिली वह थी http://tools.android.com/tech-docs/new-build-system/user-guide :

dependencies {
    flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
    flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}

मैंने कॉन्फ़िगरेशन को अलग-अलग चीजों में बदल दिया लेकिन यह काम नहीं किया!

मैं एंड्रॉइड स्टूडियो 0.8.2 का उपयोग कर रहा हूं।


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

जवाबों:


141

अंत में मुझे पता चला कि यह कैसे करना है, मैं इसे यहाँ दूसरों के लिए उसी समस्या का वर्णन करूँगा:

लाइब्रेरी बिल्ड.gradle में true के लिए publishNonDefault सेट करने के लिए महत्वपूर्ण हिस्सा है, फिर आपको उपयोगकर्ता गाइड द्वारा सुझाई गई निर्भरता को परिभाषित करना होगा।

पूरी परियोजना इस तरह होगी:

लाइब्रेरी बिल्ड.ग्रेड:

apply plugin: 'com.android.library'

android {        
    ....
    publishNonDefault true
    productFlavors {
        market1 {}
        market2 {}
    }
}

प्रोजेक्ट बिल्ड.ग्रेड:

apply plugin: 'com.android.application'

android {
    ....
    productFlavors {
        market1 {}
        market2 {}
    }
}

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

अब आप ऐप फ्लेवर और बिल्ड वेरिएंट पैनल का चयन कर सकते हैं और उसके अनुसार लाइब्रेरी का चयन किया जाएगा और चयनित स्वाद के आधार पर सभी बिल्ड और रन किए जाएंगे।

यदि आपके पास लाइब्रेरी पर आधारित कई ऐप मॉड्यूल हैं, तो एंड्रॉइड स्टूडियो वेरिएंट चयन संघर्ष के बारे में शिकायत करेगा, यह ठीक है, बस इसे अनदेखा करें।

यहां छवि विवरण दर्ज करें


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

2
1.1.0 रनिंग के रूप में, उपरोक्त समाधान अभी भी काम करने लगता है, हालांकि 1) डिबग / रिलीज बिल्ड पसंद खो जाती है और मुझे लाइब्रेरी में पाए जाने वाले एआईडीएल के साथ समस्या आती रहती है, जो बहुत बार उपयुक्त कोड का उत्पादन करने में विफल होते हैं। इस पर कोई विचार?
3c71

1
@IgorGanapolsky buildTypes का इससे कोई लेना-देना नहीं है। प्रत्येक स्वाद में सभी बिल्ड प्रकार (आमतौर पर डिबग और रिलीज़) होते हैं और ये सभी इस दृष्टिकोण के साथ काम करते हैं।
अली

1
@ एक droid यह बाजार 1 स्वाद के लिए इस्तेमाल किया जा पुस्तकालय को परिभाषित करता है!
अली

1
यह बिल्ड प्रकार "रिलीज़" करने के लिए क्यों सेट किया गया है? डिबग बिल्ड के दौरान "रिलीज़" बिल्ड प्रकार चुना जाता है?
विंडराइड सेप

35

अली जवाब के साथ एक समस्या हैं । हम अपने बिल्ड वेरिएंट में एक बहुत महत्वपूर्ण आयाम खो रहे हैं। यदि हम सभी विकल्प चाहते हैं (4 से नीचे के मेरे उदाहरण में (2 x 2)) तो हमें मुख्य मॉड्यूल build.gradle फ़ाइल में कस्टम कॉन्फ़िगरेशन को जोड़ना होगा ताकि सभी मल्टी-स्वाद मल्टी-बिल्डटाइप का उपयोग कर सकें । हमें लाइब्रेरी मॉड्यूल build.gradle फ़ाइल में publishNonDefault को सही पर सेट करना होगाBuild Variants

उदाहरण समाधान:

Lib build.gradle

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

App build.gradle

android {

    buildTypes {
        debug {
        }
        release {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

configurations {
    freeDebugCompile
    paidDebugCompile
    freeReleaseCompile
    paidReleaseCompile
}

dependencies {

    freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
    paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
    freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
    paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')

}

मेरे आवेदन में एक ही सामान करने के बाद Error:java.lang.RuntimeException: Error: more than one library with package name, कम हो गया
चेतन जोशी

21

Android प्लगइन 3.0.0 और उच्चतर के लिए अपडेट करें

आधिकारिक Android दस्तावेज़ीकरण के अनुसार - स्थानीय मॉड्यूल के लिए माइग्रेट निर्भरता कॉन्फ़िगरेशन ,

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

इसके बजाय आपको अपनी निर्भरता को कॉन्फ़िगर करना चाहिए:

dependencies {
    // This is the old method and no longer works for local
    // library modules:
    // debugImplementation project(path: ':library', configuration: 'debug')
    // releaseImplementation project(path: ':library', configuration: 'release')

    // Instead, simply use the following to take advantage of
    // variant-aware dependency resolution. You can learn more about
    // the 'implementation' configuration in the section about
    // new dependency configurations.
    implementation project(':library')

    // You can, however, keep using variant-specific configurations when
    // targeting external dependencies. The following line adds 'app-magic'
    // as a dependency to only the "debug" version of your module.

    debugImplementation 'com.example.android:app-magic:12.3'
}

तो अली के जवाब में, बदलो

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

सेवा

implementation project(':lib')

और प्लगइन स्वचालित रूप से संस्करण विशिष्ट कॉन्फ़िगरेशन का ध्यान रखेगा। आशा है कि यह दूसरों को एंड्रॉइड स्टूडियो प्लगइन को 3.0.0 और उच्चतर में अपग्रेड करने में मदद करता है।


7

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

Mylibrary के build.gradle में

apply plugin: 'com.android.library'

android {        
    ....
    flavorDimensions "mylibFlavor"

    productFlavors {
        market1
        market2
    }
}

आवेदन का निर्माण।

apply plugin: 'com.android.application'

android {
    ....
    flavorDimensions "mylibFlavor", "appFlavor"
    productFlavors {
        market1 {
            dimension "mylibFlavor"
        }
        market2 {
            dimension "mylibFlavor"
        }
        common1 {
            dimension "appFlavor"
        }
        common2 {
            dimension "appFlavor"
        }
    }
}

dependencies {
    ....
    implementation project(path: ':mylibrary')
}

सिंक के बाद, आप बिल्ड वेरिएंट विंडो में सभी विकल्प बदल सकते हैं: यहां छवि विवरण दर्ज करें


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

@ बेल्डा आपको सभी कॉपी करने की आवश्यकता नहीं है, बस एक ही उत्पाद को ऐप में रखें, मेरे नमूने के लिए, मैं आवेदन के बिल्ड.ग्रेड में market1 या market2 रख सकता हूं।
जियाजियागू

2

AAR लाइब्रेरी पर काम करने वाले जायके को प्राप्त करने के लिए, आपको अपने Android लाइब्रेरी मॉड्यूल के build.gradle फ़ाइल में defaultPublishConfig को परिभाषित करने की आवश्यकता है।

अधिक जानकारी के लिए, देखें: लाइब्रेरी प्रकाशन

पुस्तकालय प्रकाशन

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

Android {defaultPublishConfig "डिबग"}

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

Android {defaultPublishConfig "flavor1Debug"}


1

फिलहाल यह संभव नहीं है, हालांकि अगर मुझे इसकी विशेषता याद है तो वे जोड़ना चाहते हैं। (संपादित करें 2: लिंक , link2 )

संपादित करें: फिलहाल मैं defaultPublishConfigयह घोषित करने के विकल्प का उपयोग कर रहा हूं कि कौन सा पुस्तकालय संस्करण प्रकाशित हो सकता है:

android {
    defaultPublishConfig fullRelease
    defaultPublishConfig demoRelease 
}

1
इसलिए, हर बार मैं एप्लिकेशन को संकलित करने जा रहा हूं, मुझे इसे लाइब्रेरी के बिल्ड.ग्रेड में बदलना होगा?
अली

खैर, हाँ ... हर बार जब आप ऐप को एक अलग स्वाद के साथ संकलित करना चाहते हैं।
डेलब्लैंको

वास्तव में जब मैं लाइब्रेरी मॉड्यूल के लिए फ्लेवर को परिभाषित करता हूं, तो विरासत में मिला आर पैकेज ऐप मॉड्यूल नहीं पाया जाता है।
अली

आप के रूप में वर्गीकृत फ़ाइलों को सिंक किया था?
डेलब्लैंको

@ डेलब्लैंको ऐसा लगता है जैसे मैनुअल श्रम और बहुत भंगुर (डेवलपर्स आलसी हैं और अपनी बिल्ड.ग्रेडल फ़ाइलों को संशोधित करना भूल जाते हैं)।
इगोरगानापोलस्की 14

1

मुझे पता है कि यह विषय बंद कर दिया गया है, लेकिन केवल 3.0 के साथ एक अद्यतन बंद हो गया है, इसे देखें: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware और grep matchingFallbacksऔर missingDimensionStrategy। अब यह मॉड्यूल फ्लेवर के बीच निर्भरता को घोषित करने के लिए और अधिक सरल है।

... और इस सटीक मामले में gradle3.0 के साथ, जैसा कि जायके एक ही नाम साझा करते हैं, ग्रेडेल उन्हें जादुई रूप से मैप करेगा, कोई कॉन्फ़िगरेशन आवश्यक नहीं है।


मेरे लिए ऐसा लगता है कि रनटाइम जेनरेट किया गया सामान छोड़ दिया गया है। उदाहरण के तौर पर सिमोनॉट-> स्कीमैटिक्स जेनरेशन मेरे लिए नए तरीके के साथ काम नहीं कर रही है। : - /
स्टीफन स्प्रेंजर

1

मैं विभिन्न विकल्पों के संकलन मॉड्यूल में भी भाग गया।

मुझे क्या मिला है:

ऐसा लगता है कि ग्रेड 3.0 के बाद से हमें publishNonDefault trueलिब की build.gradleफाइल में जोड़ने की जरूरत नहीं है ।

विघटित होने के बाद एक वर्ग BaseExtensionने यह पाया:

public void setPublishNonDefault(boolean publishNonDefault) {
   this.logger.warn("publishNonDefault is deprecated and has no effect anymore. All variants are now published.");
}

और इसके बजाय:

dependencies {
...
   Compile project(path: ':lib', configuration: 'config1Debug')
}

हमें उपयोग करना चाहिए:

dependencies {
...
   implementation project(':lib')
}

केवल महत्वपूर्ण बात, एक configurations {...}हिस्सा जोड़ना है build.gradle

तो, एप्लिकेशन की build.gradleफ़ाइल का अंतिम संस्करण है:

buildTypes {
   debug {
      ...
   }

   release {
      ...
   }
}

flavorDimensions "productType", "serverType"
productFlavors {
   Free {
      dimension "productType"
      ...
   }
   Paid {
      dimension "productType"
      ...
   }
   Test {
      dimension "serverType"
      ...
   }
   Prod {
      dimension "serverType"
      ...
   }
}

configurations {
   FreeTestDebug
   FreeTestRelease
   FreeProdDebug
   FreeProdRelease
   PaidTestDebug
   PaidTestRelease
   PaidProdDebug
   PaidProdRelease
}

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation project(':lib')
   ...
}

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

Ps settings.gradleफ़ाइल में मॉड्यूल शामिल करना न भूलें , जैसे:

include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')

महोदय, क्या आप बता सकते हैं कि पुस्तकालय एक निश्चित विन्यास में पुस्तकालय को शामिल करने के लिए मौसम का निर्धारण कैसे करेगा? मेरा मतलब है कि मेरे पास एक मामला है जब मुझे एक निश्चित स्वाद के लिए कुछ काम का उपयोग करने की आवश्यकता होती है, लेकिन मुझे इसे अन्य स्वाद के लिए उपयोग करने की आवश्यकता नहीं है
जेनिया किरमिजा

ऐसी स्थिति में नहीं आया। लेकिन एक Google ट्यूटोरियल developer.android.com/studio/build/d dependencies "निर्भरता {...}" ब्लॉक में "कार्यान्वयन" कमांड से पहले एक उपसर्ग जोड़ने की सलाह देते हैं। Ie निर्भरताएँ {paidImplementation Project (': lib')}, या निर्भरताएँ {debugImplementation Project (': lib')), या किसी भी कई प्रकार के संयोजन संयोजन निर्भरताएँ {paidProdDebugImplementation Project (': lib')}। इसे देखें और हमें एक प्रतिक्रिया दें :)
सर्जियो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.