android सीएसवी/टीटीपीटी फ़ाइल में नामों(गुणों के साथ) की एक सूची का उपयोग करके उत्पादफ्लावर और स्रोतसेट गतिशील रूप से उत्पन्न करना




android-gradle android-build (2)

मेरे दूसरे प्रश्न को जारी रखने में यह प्रश्न, जिसे मैं आगे सुधारना चाहता हूं।

मैं sourceSets कोड के तहत निम्न कोड के साथ समूहों के स्वादों (सामान्य कॉन्फ़िगरेशन के साथ) में sourceSets :

(ऊपर लिंक्ड प्रश्न में एक प्रतिभा से मिला)

import com.android.build.gradle.api.AndroidSourceSet
android {
    sourceSets {
        [flavor2, flavor4].each { AndroidSourceSet ss ->
            ss.assets.srcDirs = ['repo-assets/flavor2']
            ss.res.srcDirs = ['repo-res/flavor2']
        }
    }
}

अब, मैं सोच रहा था कि सूची [flavor2, flavor4] को निम्न में से किसी से खींच लिया जा सकता है:

  • एक XML फ़ाइल जिस पर मैं सभी जायके प्राप्त करने के लिए पुनरावृति कर सकता हूं (जो मैं वहां रखूंगा)
  • एक सीएसवी फ़ाइल जिस पर मैं मूल्यों को पुनरावृत्त और प्राप्त कर सकता हूं।
  • एक कस्टम वर्ग जिसे मैं एक अलग फाइल में लिख सकता हूं और कक्षा में स्थिर सदस्यों से डेटा प्राप्त कर सकता हूं।

स्वाद के नाम के अतिरिक्त, मैं निम्नलिखित स्रोत को बाहरी स्रोत में से एक में रखने का इरादा रखता हूं:

  • एप्लिकेशन आईडी (जो मैं उत्पाद के लिए खींच कर productFlavors )
  • विज्ञापन इकाई आईडी (स्वाद के अनुसार दो)
  • श्रेणी आदि जैसे कुछ अन्य कस्टम मान

पोर्श: मैं पुनरावृत्त करने के लिए कोड का एक सामान्य टुकड़ा लिखना चाहता हूं और गतिशील रूप से productFlavors और sourceSets बनाना productFlavors sourceSets । मैंने लगभग 90% तक सामान्य sourceSets और एक ब्लॉक अब सभी जायके के लिए पर्याप्त है

यह अब ऐसा कुछ दिखता है:

sourceSets {
    [flavor1, flavor2, flavor3 ...].each { AndroidSourceSet ss ->
                ss.assets.srcDirs = ['repo-assets/' + ss.name.split('_')[0]]
                ss.res.srcDirs = ['repo-mipmap/' + ss.name.split('_')[0] , 'repo-strings/' + ss.name]
            }
}

इसके अलावा उपरोक्त संकेत के रूप में productFlavors लिए भी ऐसा ही करना चाहते हैं।

[flavor2, flavor4] पर: बाहरी स्रोत से ऊपर दिए गए कोड में [flavor2, flavor4] सूची प्राप्त करना (उपरोक्त सूचीबद्ध के अनुसार कुछ अतिरिक्त [flavor2, flavor4] अनुसार)

मैं जैसे तरीकों को देख रहा हूँ

productFlavors.add()
productFlavors.addAll()

लेकिन इन के उपयोग के बारे में जाने के बारे में निश्चित नहीं है I विधियों के रूप में उपलब्ध हैं मुझे यकीन है कि मैं करना चाहता हूँ जो करना संभव है।

क्या किसी ने यह किया है और कुछ संकेत दिए हैं?


XML और सीएसवी फ़ाइलों को पढ़ने के लिए आपके पास अपने हाथ पर ग्रूवी की पूर्ण शक्ति है सभी ग्रैडल लिपियों का अर्थ ग्रोवी में लिखा है। .each { Type var -> उस का भी हिस्सा है पहला परिणाम: https://.com/a/2622965/253468 :

इस तरह सीएसवी फाइल को देखते हुए:

#name,appId,ad1,ad2,category
flavor1,app.id.flavor1,adunit1324523,adunit2234234,messenger
flavor2,app.id.flavor2,adunit42346451,adunit4562,editor
flavor3,app.id.flavor2.gpe,adunit345351,adunit3545342,messenger

ग्रूवी इसे इस तरह लोड कर सकता है:

import com.android.build.gradle.BaseExtension
import com.android.build.gradle.api.AndroidSourceSet
import com.android.build.gradle.internal.dsl.ProductFlavor
// TODO get a real CSV parser, this is hacky
new File("flavors.csv").splitEachLine(",") { fields ->
    if (fields[0].charAt(0) == '#' as char) return; // skip comments
    def flavorName = fields[0];
    def baseName = flavorName.split('_')[0];
    def appId = fields[1];
    BaseExtension android = project.android // project.getExtensions().getByName('android'); 
    // productFlavors is declared as Collection, but it is a NamedDomainObjectContainer
    // if [flavorName] doesn't work, try .maybeCreate(flavorName) or .create(flavorName)
    ProductFlavor flavor = android.productFlavors[flavorName];
    AndroidSourceSet sourceSet = android.sourceSets[flavorName];
    flavor.applicationId = appId;
    sourceSet.res.srcDirs = [] // clear
    sourceSet.res.srcDir 'repo-mipmap/' + baseName
    sourceSet.res.srcDir 'repo-strings/' + flavorName
}

पठनीयता और कोड पूरा करने के लिए प्रकारों को आयात किया जाता है, आप def साथ किसी भी चर प्रकार को बदल सकते हैं और यह अभी भी काम करेगा। ये प्रकार ये हैं कि जब आप नियमित android { ... } कॉन्फ़िगरेशन कर रहे हैं तब क्या इस्तेमाल किया जा रहा है आंतरिक प्रकार किसी भी समय बदल सकते हैं, वास्तव में मैं 1.5 के साथ काम कर रहा हूं, वे पहले से 2.0 में बदल सकते हैं।


अंत में मुझे यह काम करने के लिए मिल गया:

MyFlavor भीतर एक कस्टम क्लास MyFlavor build.gradle और सीएसवी फ़ाइल से प्रत्येक स्वाद MyFlavor एक ArrayList को MyFlavor

class MyFlavor {
    public String flavorname;
    public String basename;
    public String appid;
    public String bannerid;
    public String interstitialid;
    public String category;
}

def ArrayList<MyFlavor> myFlavors = new ArrayList<>();

new File('app/flavors.csv').eachLine {
    String[] values = "$it".split(',');
    MyFlavor f = new MyFlavor();
    f.flavorname = values[0];
    f.basename = values[0].split('_')[0];
    f.appid = values[1];
    f.bannerid = values[2];
    f.interstitialid = values[3];
    if(values[0].contains('_')) f.category= "state"
    else f.category = "country";
    myFlavors.add(f);
}

फिर ArrayList पर गतिशील रूप से productFlavors और sourceSets बनाने के लिए निम्न प्रकार है:

productFlavors {
    myFlavors.each { MyFlavor f ->
        "$f.flavorname" {
            applicationId = "$f.appid"
            buildConfigField 'String', 'BANNER_ID', "\"" + "$f.bannerid" + "\""
            buildConfigField 'String', 'INTERSTITIAL_ID', "\"" + "$f.interstitialid" + "\""
            buildConfigField 'String', 'CATEGORY', "\"" + "$f.category" + "\""
        }
    }
}
sourceSets {
    myFlavors.each { MyFlavor f ->
        "$f.flavorname" {
            assets.srcDirs = ['repo-assets/' + "$f.basename"]
            res.srcDirs = ['repo-mipmap/' + "$f.basename" , 'repo-strings/' + "$f.flavorname"]
        }

    }
}

उम्मीद है कि यह किसी को मदद करता है मैं कोड की 1000s से छुटकारा पाने में सफल रहा (क्योंकि मेरे पास बहुत सारे स्वाद हैं) और इन 10 एस लाइनों को नीचे लाने के लिए यहां देखें।





android-sourcesets