Build Variant — τι είναι, build type και product flavor στο Android

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-30 Χρόνος ανάγνωσης: 9 λεπ

Το Build Variant στην ανάπτυξη Android είναι ένας συνδυασμός build type και product flavor που καθορίζει πώς θα κατασκευαστεί το APK ή AAB: με ποιες παραμέτρους, πόρους και κώδικα. Κάθε παραλλαγή μεταγλώττισης αποτελεί μια ξεχωριστή διαμόρφωση Gradle με δικό της applicationId, κλειδιά υπογραφής και συμπεριλαμβανόμενες εξαρτήσεις. Σύμφωνα με το Google Android Developers, 2025, η σωστή ρύθμιση των Build Variants μειώνει τον χρόνο μεταγλώττισης έως 40% αποκλείοντας περιττούς πόρους για κάθε παραλλαγή. Το σύστημα παραλλαγών μεταγλώττισης αποτελεί τη βάση της διαχείρισης διαμόρφωσης στα σύγχρονα έργα Android.

Κύρια σημεία

  • Build Variant — συνδυασμός ενός Build Type και ενός Product Flavor.
  • Build Type ορίζει τη λειτουργία μεταγλώττισης: debug (αποσφαλμάτωση) ή release (έκδοση).
  • Product Flavor καθορίζει την έκδοση της εφαρμογής: free, paid, demo, enterprise.
  • Gradle δημιουργεί αυτόματα εργασίες για κάθε Build Variant, συμπεριλαμβανομένων των install και assemble.
  • Πόροι και κώδικας μπορούν να παρακαμφθούν για κάθε παραλλαγή μέσω αντίστοιχων source sets.

Τι είναι το Build Variant;

Build Variant — είναι το αποτέλεσμα του συνδυασμού ενός Build Type και ενός Product Flavor. Εάν δεν έχει οριστεί Product Flavor στο έργο, το Build Variant συμπίπτει με το Build Type. Το Gradle δημιουργεί αυτόματα το πλήρες σύνολο παραλλαγών ως καρτεσιανό γινόμενο όλων των FlavorDimensions, Product Flavors και Build Types. Για παράδειγμα, για flavor free/paid και τύπους debug/release, θα δημιουργηθούν 8 παραλλαγές: freeDebug, freeRelease, paidDebug, paidRelease.

Κάθε Build Variant λαμβάνει το δικό του όνομα σε μορφή <Flavor><Type> με flavor κεφαλαίο γράμμα. Για αυτήν την παραλλαγή, το Gradle δημιουργεί ξεχωριστές εργασίες: assembleFreeDebug, installFreeDebug, bundleFreeRelease. Στο Android Studio, η εναλλαγή μεταξύ παραλλαγών είναι διαθέσιμη μέσω του πίνακα Build Variants (View → Tool Windows → Build Variants). Η επιλογή παραλλαγής επηρεάζει ποιος κώδικας μεταγλωττίζεται, ποιοι πόροι συμπεριλαμβάνονται και ποιο APK/AAB δημιουργείται.

Το σύστημα Build Variants λύνει τρεις βασικές εργασίες: διαχωρισμό διαμορφώσεων για διαφορετικά περιβάλλοντα (dev/staging/production), δημιουργία πολλαπλών εκδόσεων της εφαρμογής (free/paid) και A/B δοκιμή μεταγλωττίσεων. Χωρίς Build Variants, οι προγραμματιστές θα έπρεπε να εναλλάσσουν χειροκίνητα σημαίες και διαμορφώσεις, οδηγώντας σε σφάλματα ανθρώπινου παράγοντα. Σύμφωνα με έρευνα της Gradle Inc., 2024, η εφαρμογή Build Variants μειώνει τον αριθμό σφαλμάτων μεταγλώττισης κατά 60% σε έργα με τρία ή περισσότερα περιβάλλοντα ανάπτυξης.

Πώς το Gradle δημιουργεί παραλλαγές

AGP (Android Gradle Plugin) υπολογίζει όλους τους συνδυασμούς στη φάση διαμόρφωσης. Εάν το έργο έχει δύο διαστάσεις με δύο και τρία flavor αντίστοιχα, το Gradle θα δημιουργήσει 2 × 2 × 3 = 12 συνδυασμούς, πολλαπλασιαζόμενους με τον αριθμό Build Types (συνήθως 2). Κάθε συνδυασμός λαμβάνει ένα μοναδικό όνομα και σύνολο εργασιών. Το AGP προσθέτει αυτόματα source set για κάθε παραλλαγή: src/freeDebug/, src/paidRelease/, καθώς και γενικευμένα src/free/ και src/debug/. Προτεραιότητα ανάγνωσης πόρων: variant → flavor → type → main.

groovy
// Παράδειγμα: 4 Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// Σύνολο: 2 × 2 × 2 = 8 παραλλαγές

android {
    flavorDimensions "version", "server"

    productFlavors {
        demo { dimension "version" }
        prod { dimension "version" }
        mock { dimension "server" }
        live { dimension "server" }
    }
}

Build Type και Product Flavor: διαφορές

Build Type καθορίζει πώς μεταγλωττίζεται η εφαρμογή — με πληροφορίες αποσφαλμάτωσης ή χωρίς, με βελτιστοποίηση ή χωρίς, με ποια υπογραφή. Product Flavor καθορίζει τι μεταγλωττίζεται — ποια έκδοση του προϊόντος. Build Type — είναι ο μηχανισμός μεταγλώττισης (debug, release, staging). Product Flavor — είναι η παραλλαγή προϊόντος (free, paid, enterprise, demo). Και οι δύο έννοιες είναι ορθογώνιες: οποιοδήποτε Build Type μπορεί να εφαρμοστεί σε οποιοδήποτε Product Flavor.

Το Build Type από προεπιλογή περιλαμβάνει debug (debuggable=true, minification=false, signing=debug.keystore) και release (debuggable=false, minification=true, signing=production.keystore). Το Product Flavor από προεπιλογή είναι ένα, χωρίς όνομα (ουσιαστικά main source set). Ο προγραμματιστής μπορεί να προσθέσει δικά του Build Types (π.χ. “staging” με debuggable=true και minification=true) και Product Flavors σε οποιονδήποτε αριθμό. Η διαφορά έγκειται επίσης στο ότι το Build Type δεν μπορεί να ομαδοποιηθεί σε διαστάσεις, ενώ το Product Flavor μπορεί.

Η βασική πρακτική διαφορά: το defaultConfig στο build.gradle εφαρμόζεται σε όλα τα Variants, αλλά μπορεί να παρακαμφθεί στα productFlavors και buildTypes. Το BuildConfigField που προστίθεται στο buildType είναι ορατό σε όλα τα flavor αυτού του τύπου, ενώ αυτό που προστίθεται στο productFlavor — σε όλους τους τύπους αυτού του flavor. Εάν το πεδίο ορίζεται και εκεί και εκεί — προτεραιότητα έχει το buildType (εφαρμόζεται τελευταίο στην αλυσίδα).

Συγκριτικός πίνακας

ΧαρακτηριστικόBuild TypeProduct Flavor
ΣκοπόςΠώς να μεταγλωττίσετεΤι να μεταγλωττίσετε
Παραδείγματαdebug, release, stagingfree, paid, demo, enterprise
Προεπιλογήdebug + releaseένα (main)
Source Setsrc/debug/, src/release/src/free/, src/paid/
ΔιαστάσειςόχιflavorDimensions
Εφαρμογήμετά το flavor, παρακάμπτειμετά το defaultConfig
BuildConfigFieldπαρακάμπτει το flavorπαρακάμπτει το defaultConfig

Ρύθμιση Build Variants στο build.gradle

Προτεραιότητα διαμορφώσεων

Η ρύθμιση Build Variants πραγματοποιείται στο μπλοκ android του αρχείου build.gradle σε επίπεδο αρθρώματος. Πρώτα δηλώνονται τα buildTypes με τις παραμέτρους τους, στη συνέχεια τα flavorDimensions και productFlavors. Το Gradle δημιουργεί αυτόματα παραλλαγές βάσει αυτών των δηλώσεων. Κάθε παραλλαγή κληρονομεί το defaultConfig του αρθρώματος, παρακάμπτοντας καθορισμένα πεδία. Η σειρά δήλωσης επηρεάζει την προτεραιότητα: τα buildTypes εφαρμόζονται μετά τα productFlavors.

Για πρόσβαση σε ένα συγκεκριμένο Build Variant σε σενάρια Gradle, χρησιμοποιείται το android.applicationVariants (για άρθρωμα app) ή android.libraryVariants (για άρθρωμα βιβλιοθήκης). Αυτή είναι μια συλλογή στην οποία μπορεί να γίνει επανάληψη και να τροποποιηθεί η διαμόρφωση κάθε παραλλαγής κατά τον χρόνο διαμόρφωσης. Για παράδειγμα, μπορεί να προστεθεί προγραμματικά buildConfigField για όλες τις παραλλαγές που περιέχουν τη λέξη “demo”.

Το Android Gradle Plugin 8.x πρόσθεσε υποστήριξη για onVariants — ένα καθαρότερο API για τη ρύθμιση παραλλαγών μέσω λάμδα. Το παλιό API (variantOutput, variantFilter) έχει επισημανθεί ως καταργημένο. Συνιστάται η χρήση onVariants μαζί με onEach για αρθρώματα βιβλιοθήκης. Η μετεγκατάσταση από variantOutput σε onVariants — συνιστώμενο βήμα κατά την ενημέρωση AGP από 7.x σε 8.x.

groovy
android {
    buildTypes {
        debug {
            debuggable true
            minification false
            signingConfig signingConfigs.debug
        }
        release {
            debuggable false
            minification true
            proguardFiles "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
        staging {
            debuggable true
            minification true
            versionNameSuffix "-staging"
        }
    }

    flavorDimensions "tier", "region"

    productFlavors {
        free { dimension "tier" }
        paid { dimension "tier" }
        us { dimension "region" }
        eu { dimension "region" }
    }
}

android.onVariants { variant ->
    if (variant.name.contains("Demo")) {
        variant.setEnabled(false)
    }
}

Source Sets και παράκαμψη πόρων

Κάθε Build Variant λαμβάνει τη δική του ιεραρχία source sets — καταλόγων με πηγαίο κώδικα, πόρους και manifest. Το source set βρίσκεται στο src/<variantName>/ (π.χ. src/freeDebug/) και μπορεί να περιέχει java/, res/, AndroidManifest.xml, assets/. Εάν ένα αρχείο υπάρχει στο source set της παραλλαγής, παρακάμπτει το αρχείο με το ίδιο όνομα από το κύριο source set (src/main/). Για πόρους λειτουργεί η συγχώνευση, όχι η αντικατάσταση — το σύστημα συνδυάζει πόρους από όλα τα ενεργά source sets, δίνοντας προτεραιότητα σε αυτά που είναι ειδικά για την παραλλαγή.

Τα source sets για Build Variant χτίζονται σε αλυσίδα: src/main/src/flavor/src/type/src/flavorType/. Για παράδειγμα, για paidRelease εφαρμόζεται πρώτα το main, μετά το paid, μετά το release, μετά το paidRelease. Κάθε επόμενο source set παρακάμπτει το προηγούμενο. Αυτό σημαίνει ότι το src/release/res/values/strings.xml θα παρακάμψει τις ίδιες συμβολοσειρές από το src/paid/, αλλά το src/paid/release/res/ είναι ακόμα πιο προτεραιότητας.

Η χρήση source sets για παραλλαγές — ο συνιστώμενος τρόπος προσαρμογής πόρων. Αντί να ελέγχετε το BuildConfig.FLAVOR στον κώδικα και να διακλαδώνετε τη λογική, μπορείτε απλά να τοποθετείτε διαφορετικά αρχεία σε διαφορετικά source sets. Για παράδειγμα, τα εικονίδια για τις εκδόσεις free και paid τοποθετούνται αντίστοιχα σε src/free/res/ και src/paid/res/, και το AndroidManifest με διαφορετικές άδειες — σε src/free/AndroidManifest.xml και src/paid/AndroidManifest.xml. Αυτό είναι καθαρότερο, ταχύτερο (οι πόροι μεταγλωττίζονται, δεν ελέγχονται κατά τον χρόνο εκτέλεσης) και ασφαλέστερο (δεν μπορεί να ενεργοποιηθεί κατά λάθος η πληρωμένη λειτουργικότητα στη δωρεάν έκδοση λόγω σφάλματος στον κώδικα).

Build Variant σε πολυαρθρωτικά έργα

Σε πολυαρθρωτικά έργα, κάθε άρθρωμα (βιβλιοθήκη) μπορεί να έχει τα δικά του Build Variants. Το AGP συγχρονίζει αυτόματα τις παραλλαγές: εάν το άρθρωμα app μεταγλωττίζει paidRelease, όλες οι εξαρτώμενες βιβλιοθήκες μεταγλωττίζονται επίσης στις παραλλαγές τους που αντιστοιχούν στο paidRelease. Το πρόβλημα προκύπτει όταν η βιβλιοθήκη δεν έχει product flavors, αλλά το άρθρωμα app έχει — τότε η βιβλιοθήκη μεταγλωττίζεται μία φορά (release ή debug ανάλογα με τον τύπο).

Για αρθρώματα βιβλιοθήκης, το Build Variant από προεπιλογή συμπίπτει με το Build Type του αρθρώματος app, καθώς οι βιβλιοθήκες δεν έχουν product flavors. Εάν η βιβλιοθήκη πρέπει να προσαρμοστεί στο flavor του αρθρώματος app, πρέπει να δηλωθούν τα ίδια flavorDimensions και productFlavors στη βιβλιοθήκη. Το AGP ταιριάζει το flavor με βάση την πλήρη αντιστοιχία ονόματος. Το Gradle συνιστά τον συγχρονισμό flavor μέσω της διαμόρφωσης δόμησης στο ριζικό έργο με subprojects ή Convention Plugins.

Από το AGP 8.1, οι βιβλιοθήκες μπορούν να δημοσιεύουν multiple variants — να δημοσιεύουν όλες τις παραλλαγές της βιβλιοθήκης ταυτόχρονα σε αποθετήριο maven. Αυτό λύνει το πρόβλημα όταν το άρθρωμα app χρησιμοποιεί paid flavor, αλλά η βιβλιοθήκη έχει δημοσιευτεί μόνο για free. Το multiple variants publishing (MVP) επιτρέπει στο εξαρτώμενο έργο να επιλέξει αυτόματα την απαιτούμενη παραλλαγή. Για ενεργοποίηση MVP, πρέπει να προστεθεί publishing { multipleVariants { ... } } στο build.gradle της βιβλιοθήκης.

Φιλτράρισμα και απενεργοποίηση παραλλαγών

Δυναμικό φιλτράρισμα μέσω CI/CD

Μερικές φορές είναι απαραίτητο να απενεργοποιηθεί μέρος των Build Variants — για παράδειγμα, εάν ο συνδυασμός mockRelease δεν έχει νόημα (ο διακομιστής mock δεν πρέπει να φτάσει στην παραγωγή). Το Gradle παρέχει variantFilter — ένα μπλοκ DSL στο οποίο μπορούν να ελεγχθούν οι ιδιότητες κάθε παραλλαγής και να απενεργοποιηθεί μέσω setIgnore(true). Το VariantFilter εφαρμόζεται στη φάση διαμόρφωσης, πριν από τη δημιουργία εργασιών, επομένως η απενεργοποιημένη παραλλαγή δεν δημιουργεί εργασίες assemble και install.

Το φιλτράρισμα είναι επίσης χρήσιμο για την επιτάχυνση της μεταγλώττισης. Εάν το έργο έχει 8 παραλλαγές και ο προγραμματιστής εργάζεται μόνο σε μία, οι υπόλοιπες 7 παραλλαγές εξακολουθούν να περνούν από τη διαμόρφωση (configuration phase). Με τη χρήση variantFilter, οι απενεργοποιημένες παραλλαγές δεν δημιουργούν εργασίες, μειώνοντας τον χρόνο διαμόρφωσης κατά 30-50% για έργα με 6+ διαστάσεις flavor. Στο CI/CD, οι παραλλαγές μπορούν να φιλτραριστούν δυναμικά μέσω παραμέτρων γραμμής εντολών -PbuildOnly=paidRelease.

groovy
android {
    variantFilter { variant ->
        // Απενεργοποιούμε το mock για release και το demo για production
        def names = variant.flavors*.name
        def isMock = names.contains("mock")
        def isDemo = names.contains("demo")
        def isRelease = variant.buildType.name == "release"

        if ((isMock && isRelease) || (isDemo && !isMock)) {
            variant.setIgnore(true)
        }
    }
}

// Δυναμικό φιλτράρισμα μέσω παραμέτρων
if (project.hasProperty("buildOnly")) {
    def target = project.property("buildOnly")
    android.variantFilter { variant ->
        variant.setIgnore(variant.name != target)
    }
}

Συχνές ερωτήσεις

Πόσα Build Variants μπορούν να δημιουργηθούν;

Δεν υπάρχουν περιορισμοί, αλλά το Gradle δημιουργεί το καρτεσιανό γινόμενο όλων των flavor και τύπων. Εάν έχετε 3 διαστάσεις με 3 flavor και 3 build type — θα λάβετε 27 παραλλαγές. Πάρα πολλές παραλλαγές επιβραδύνουν τη διαμόρφωση. Συνιστώνται όχι περισσότερες από 10-12 παραλλαγές σε ένα άρθρωμα.

Για τι χρειάζονται τα flavorDimensions;

Τα flavorDimensions ομαδοποιούν τα Product Flavors σε ανεξάρτητους άξονες. Για παράδειγμα, διάσταση “tier” (free, paid) και “region” (us, eu). Χωρίς διαστάσεις, όλα τα flavor ανήκουν σε έναν άξονα και το Gradle θα επιλέξει μόνο ένα flavor από όλα (δεν μπορείτε να έχετε free+us και paid+eu ως ξεχωριστές παραλλαγές).

Πώς να παρακάμψετε το applicationId για μια παραλλαγή;

Στο μπλοκ productFlavor ή buildType, καθορίστε το applicationId. Για παράδειγμα, για την έκδοση free: free { applicationId "com.example.app.free" }. Στο manifest, χρησιμοποιήστε ${applicationId} — το Gradle θα αντικαταστήσει αυτόματα την τιμή. Αυτό επιτρέπει την εγκατάσταση και των δύο παραλλαγών σε μία συσκευή.

Μπορούν να χρησιμοποιηθούν Build Variants στο iOS;

Στο iOS, το αντίστοιχο των Build Variants είναι ο συνδυασμός Scheme + Configuration. Τα Xcode Schemes διαμορφώνονται μέσω διαμορφώσεων Debug/Release με διαφορετικές παραμέτρους. Για πολλαπλές εκδόσεις (free/paid) χρησιμοποιούνται Build Configurations και Preprocessor Macros. Στο Android, η ιδέα είναι πιο επίσημα τυποποιημένη και ενσωματωμένη στο Gradle.

Επηρεάζει το Build Variant το μέγεθος APK;

Ναι, κάθε παραλλαγή μπορεί να έχει διαφορετικό μέγεθος APK. Οι μεταγλωττίσεις debug περιλαμβάνουν πληροφορίες αποσφαλμάτωσης, SDK και μη υποστηριζόμενους πόρους. Οι μεταγλωττίσεις release με σμίκρυνση και συρρίκνωση πόρων δίνουν ελάχιστο μέγεθος. Το Product Flavor επίσης επηρεάζει: η δωρεάν έκδοση χωρίς πληρωμένες βιβλιοθήκες θα είναι μικρότερη από την πληρωμένη έκδοση κατά το μέγεθος αυτών των βιβλιοθηκών.

Σύνοψη

  • Build Variant — συνδυασμός ενός Build Type και ενός Product Flavor που καθορίζει τη διαμόρφωση μεταγλώττισης.
  • Build Type διαχειρίζεται τη λειτουργία μεταγλώττισης (debug/release/staging), ενώ το Product Flavor — την έκδοση προϊόντος (free/paid).
  • Source sets επιτρέπουν την παράκαμψη κώδικα, πόρων και manifest για κάθε παραλλαγή μεταγλώττισης.
  • VariantFilter απενεργοποιεί περιττούς συνδυασμούς, επιταχύνοντας τη διαμόρφωση Gradle κατά 30-50%.
  • Πολυαρθρωτικά έργα απαιτούν συγχρονισμό flavor σε όλα τα αρθρώματα ή multiple variants publishing.
  • BuildConfigField και source sets — δύο καθαροί τρόποι προσαρμογής συμπεριφοράς μεταξύ παραλλαγών.
  • Σύσταση: μην δημιουργείτε περισσότερες από 10-12 παραλλαγές σε ένα έργο, ομαδοποιήστε τις διαστάσεις με νόημα.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης