پیکربندی انواع ساخت

این صفحه به شما نشان می دهد که چگونه می توانید انواع ساخت را برای ایجاد نسخه های مختلف برنامه خود از یک پروژه واحد پیکربندی کنید و چگونه وابستگی ها و پیکربندی های امضای خود را به درستی مدیریت کنید.

هر نوع ساخت نشان دهنده نسخه متفاوتی از برنامه شما است که می توانید بسازید. به عنوان مثال، ممکن است بخواهید یک نسخه از برنامه خود را بسازید که رایگان با مجموعه ای محدود از محتوا، و نسخه دیگری پولی که شامل موارد بیشتری باشد. همچنین می‌توانید نسخه‌های مختلفی از برنامه خود را بسازید که دستگاه‌های مختلف را هدف قرار می‌دهند، بر اساس سطح API یا سایر تغییرات دستگاه.

انواع ساخت نتیجه استفاده Gradle از مجموعه ای خاص از قوانین برای ترکیب تنظیمات، کد و منابع پیکربندی شده در انواع ساخت و طعم محصول شماست. اگرچه شما انواع ساخت را مستقیماً پیکربندی نمی‌کنید، اما انواع ساخت و طعم‌های محصول را که آنها را تشکیل می‌دهند پیکربندی می‌کنید.

برای مثال، طعم محصول «دمو» ممکن است ویژگی‌ها و الزامات دستگاه را مشخص کند، مانند کد منبع سفارشی، منابع، و حداقل سطوح API، در حالی که نوع ساخت «اشکال‌زدایی» تنظیمات مختلف ساخت و بسته‌بندی، مانند گزینه‌های اشکال‌زدایی و امضا را اعمال می‌کند. کلیدها نوع ساختی که این دو را ترکیب می‌کند، نسخه «demoDebug» برنامه شما است و ترکیبی از پیکربندی‌ها و منابع موجود در طعم محصول «دمو»، نوع ساخت «اشکال‌زدایی» و مجموعه main/ منبع را شامل می‌شود.

پیکربندی انواع ساخت

می توانید انواع ساخت را در بلوک android فایل build.gradle.kts در سطح ماژول ایجاد و پیکربندی کنید. هنگامی که یک ماژول جدید ایجاد می کنید، Android Studio به طور خودکار انواع ساخت دیباگ و انتشار را ایجاد می کند. اگرچه نوع ساخت اشکال‌زدایی در فایل پیکربندی ساخت ظاهر نمی‌شود، Android Studio آن را با debuggable true پیکربندی می‌کند. این به شما امکان می‌دهد برنامه را در دستگاه‌های Android ایمن اشکال‌زدایی کنید و امضای برنامه را با یک فروشگاه کلید اشکال زدایی عمومی پیکربندی کنید.

اگر می‌خواهید تنظیمات خاصی را اضافه یا تغییر دهید، می‌توانید نوع ساخت اشکال‌زدایی را به پیکربندی خود اضافه کنید. نمونه زیر یک applicationIdSuffix برای نوع ساخت اشکال‌زدایی مشخص می‌کند و یک نوع ساخت «staging» را پیکربندی می‌کند که با استفاده از تنظیمات از نوع ساخت اشکال‌زدایی مقداردهی اولیه می‌شود:

کاتلین

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
        ...
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }

        getByName("debug") {
            applicationIdSuffix = ".debug"
            isDebuggable = true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        create("staging") {
            initWith(getByName("debug"))
            manifestPlaceholders["hostName"] = "internal.example.com"
            applicationIdSuffix = ".debugStaging"
        }
    }
}

شیار

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
        ...
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
            debuggable true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix ".debugStaging"
        }
    }
}

توجه: هنگامی که در فایل پیکربندی ساخت، تغییراتی ایجاد می کنید، Android Studio از شما می خواهد که پروژه خود را با پیکربندی جدید همگام سازی کنید. برای همگام سازی پروژه خود، روی همگام سازی اکنون در نوار اعلان که هنگام ایجاد تغییر ظاهر می شود کلیک کنید یا روی همگام سازی پروژه کلیک کنید. از نوار ابزار اگر Android Studio متوجه هر گونه خطایی در پیکربندی شما شود، پنجره Messages برای توصیف مشکل ظاهر می شود.

برای کسب اطلاعات بیشتر در مورد تمام ویژگی هایی که می توانید با انواع ساخت پیکربندی کنید، مرجع BuildType را بخوانید.

طعم های محصول را پیکربندی کنید

ایجاد طعم محصول مشابه ایجاد انواع ساخت است. طعم های محصول را به بلوک productFlavors در پیکربندی ساخت خود اضافه کنید و تنظیماتی را که می خواهید اضافه کنید. طعم های محصول از ویژگی های defaultConfig پشتیبانی می کنند، زیرا defaultConfig در واقع به کلاس ProductFlavor تعلق دارد. این بدان معناست که می‌توانید پیکربندی پایه را برای همه طعم‌ها در بلوک defaultConfig ارائه کنید و هر طعم می‌تواند هر یک از این مقادیر پیش‌فرض را تغییر دهد، مانند applicationId . برای کسب اطلاعات بیشتر در مورد شناسه برنامه، تنظیم شناسه برنامه را بخوانید.

توجه: همچنان باید نام بسته را با استفاده از ویژگی package در فایل main/ مانیفست مشخص کنید. همچنین باید از آن نام بسته در کد منبع خود برای ارجاع به کلاس R یا حل هر گونه فعالیت یا ثبت خدمات نسبی استفاده کنید. این به شما امکان می دهد از applicationId استفاده کنید تا به هر محصول یک شناسه منحصر به فرد برای بسته بندی و توزیع بدون نیاز به تغییر کد منبع خود بدهید.

همه طعم ها باید به یک بعد طعم نامگذاری شده تعلق داشته باشند که گروهی از طعم های محصول است. شما باید همه طعم ها را به یک بعد طعم اختصاص دهید. در غیر این صورت با خطای ساخت زیر مواجه خواهید شد.

  Error: All flavors must now belong to a named flavor dimension.
  The flavor 'flavor_name' is not assigned to a flavor dimension.

اگر یک ماژول معین فقط یک بعد طعم را مشخص کند، افزونه Android Gradle به طور خودکار همه طعم‌های ماژول را به آن بعد اختصاص می‌دهد.

نمونه کد زیر یک بعد طعم به نام "نسخه" ایجاد می کند و طعم های "دمو" و "کامل" محصول را اضافه می کند. این طعم ها applicationIdSuffix و versionNameSuffix خود را ارائه می دهند:

کاتلین

android {
    ...
    defaultConfig {...}
    buildTypes {
        getByName("debug"){...}
        getByName("release"){...}
    }
    // Specifies one flavor dimension.
    flavorDimensions += "version"
    productFlavors {
        create("demo") {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension = "version"
            applicationIdSuffix = ".demo"
            versionNameSuffix = "-demo"
        }
        create("full") {
            dimension = "version"
            applicationIdSuffix = ".full"
            versionNameSuffix = "-full"
        }
    }
}

شیار

android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

توجه: اگر برنامه قدیمی دارید (که قبل از آگوست 2021 ایجاد شده است) که با استفاده از APK ها در Google Play توزیع می کنید، برای توزیع برنامه خود با استفاده از پشتیبانی از چندین APK در Google Play، یک مقدار applicationId یکسان را به همه گونه ها اختصاص دهید و به هر گونه یک versionCode متفاوت بدهید. . برای توزیع انواع مختلف برنامه خود به عنوان برنامه های جداگانه در Google Play، باید یک applicationId متفاوت به هر گونه اختصاص دهید.

پس از ایجاد و پیکربندی طعم های محصول خود، روی همگام سازی اکنون در نوار اعلان کلیک کنید. هنگامی که همگام سازی کامل شد، Gradle به طور خودکار انواع ساخت را بر اساس نوع ساخت و طعم محصول شما ایجاد می کند و آنها را بر اساس <product-flavor><Build-Type> نام گذاری می کند. به عنوان مثال، اگر طعم های محصول "دمو" و "کامل" را ایجاد کرده باشید و انواع ساخت پیش فرض "debug" و "release" را حفظ کرده باشید، Gradle انواع ساخت زیر را ایجاد می کند:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

برای انتخاب نوع ساخت و اجرا، به Build > Select Build Variant بروید و یک نوع ساخت را از منو انتخاب کنید. برای شروع سفارشی‌سازی هر نوع ساخت با ویژگی‌ها و منابع خاص خود، باید مجموعه‌های منبع را ایجاد و مدیریت کنید ، همانطور که در این صفحه توضیح داده شده است.

شناسه برنامه را برای انواع ساخت تغییر دهید

هنگامی که یک APK یا AAB برای برنامه خود می سازید، ابزارهای ساخت برنامه را با شناسه برنامه تعریف شده در بلوک defaultConfig از فایل build.gradle.kts تگ می کنند، همانطور که در مثال زیر نشان داده شده است. با این حال، اگر می‌خواهید نسخه‌های مختلفی از برنامه‌تان را ایجاد کنید تا به‌صورت فهرست‌های جداگانه در فروشگاه Google Play ظاهر شوند، مانند نسخه‌های «رایگان» و «حرفه‌ای»، باید نسخه‌های ساخت جداگانه‌ای ایجاد کنید که هر کدام شناسه برنامه متفاوتی داشته باشند.

در این مورد، هر نوع ساخت را به عنوان طعم محصول جداگانه تعریف کنید. برای هر طعم داخل بلوک productFlavors ، می‌توانید ویژگی applicationId را دوباره تعریف کنید، یا در عوض می‌توانید یک بخش را با استفاده از applicationIdSuffix به شناسه برنامه پیش‌فرض اضافه کنید، همانطور که در اینجا نشان داده شده است:

کاتلین

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
        }
    }
}

شیار

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        pro {
            applicationIdSuffix ".pro"
        }
    }
}

به این ترتیب، شناسه برنامه برای طعم محصول "رایگان" "com.example.myapp.free" است.

همچنین می توانید از applicationIdSuffix برای اضافه کردن یک بخش بر اساس نوع ساخت خود استفاده کنید، همانطور که در اینجا نشان داده شده است:

کاتلین

android {
    ...
    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
        }
    }
}

شیار

android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

از آنجایی که Gradle پیکربندی نوع ساخت را بعد از طعم محصول اعمال می کند، شناسه برنامه برای نوع ساخت "اشکال زدایی رایگان" "com.example.myapp.free.debug" است. این زمانی مفید است که می‌خواهید هم اشکال زدایی و هم نسخه انتشار را روی یک دستگاه داشته باشید، زیرا هیچ دو برنامه‌ای نمی‌توانند شناسه برنامه یکسانی داشته باشند.

اگر یک برنامه قدیمی (که قبل از اوت 2021 ایجاد شده است) دارید که با استفاده از APK در Google Play توزیع می‌کنید، و می‌خواهید از همان فهرست برنامه برای توزیع چندین APK استفاده کنید که هر کدام پیکربندی دستگاه متفاوتی مانند سطح API را هدف قرار می‌دهند، پس شما باید از همان شناسه برنامه برای هر نوع ساخت استفاده کند اما به هر APK versionCode متفاوتی بدهد. برای اطلاعات بیشتر، درباره پشتیبانی از APK چندگانه بخوانید. انتشار با استفاده از AAB ها بی تاثیر است، زیرا از یک مصنوع استفاده می کند که به طور پیش فرض از یک کد نسخه و شناسه برنامه استفاده می کند.

نکته: اگر نیاز به ارجاع شناسه برنامه در فایل مانیفست خود دارید، می‌توانید از مکان‌نمای ${applicationId} در هر ویژگی مانیفست استفاده کنید. در طول ساخت، Gradle این تگ را با شناسه واقعی برنامه جایگزین می کند. برای اطلاعات بیشتر، به تزریق متغیرهای ساخت به مانیفست مراجعه کنید.

چندین طعم محصول را با ابعاد طعم ترکیب کنید

در برخی موارد، ممکن است بخواهید پیکربندی هایی را از طعم های مختلف محصول ترکیب کنید. برای مثال، ممکن است بخواهید پیکربندی‌های مختلفی را برای طعم‌های محصول «کامل» و «دمو» ایجاد کنید که بر اساس سطح API هستند. برای انجام این کار، افزونه Android Gradle به شما امکان می دهد چندین گروه از طعم های محصول را به عنوان ابعاد طعم ایجاد کنید.

هنگام ساخت اپلیکیشن، Gradle یک پیکربندی طعم محصول را از هر بعد طعمی که تعریف می‌کنید، همراه با پیکربندی نوع ساخت ترکیب می‌کند تا نوع ساخت نهایی را ایجاد کند. Gradle طعم های محصول را که متعلق به یک بعد طعم هستند ترکیب نمی کند.

نمونه کد زیر از ویژگی flavorDimensions برای ایجاد یک بعد طعم "mode" برای گروه بندی طعم های محصول "full" و "demo" و یک بعد طعم "api" برای گروه بندی تنظیمات طعم محصول بر اساس سطح API استفاده می کند:

کاتلین

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdk = 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.
      versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdk = 23
      versionCode = 20000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdk = 21
      versionCode = 10000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

شیار

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.

      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion 23
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

تعداد انواع ساختی که Gradle ایجاد می کند برابر است با حاصل ضرب تعداد طعم ها در هر بعد طعم و تعداد انواع ساختی که پیکربندی می کنید. وقتی Gradle هر نوع ساخت یا مصنوعات مربوطه را نام می‌برد، طعم‌های محصول متعلق به بعد طعم با اولویت بالاتر ابتدا ظاهر می‌شوند، سپس طعم‌های مربوط به ابعاد با اولویت پایین‌تر و سپس نوع ساخت ظاهر می‌شوند.

با استفاده از پیکربندی ساخت قبلی به عنوان مثال، Gradle در مجموع 12 نوع ساخت با طرح نامگذاری زیر ایجاد می کند:

  • نوع ساخت: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
  • APK مربوطه: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
  • به عنوان مثال،
    نوع ساخت: minApi24DemoDebug
    APK مربوطه: app-minApi24-demo-debug.apk

علاوه بر دایرکتوری‌های مجموعه منبعی که می‌توانید برای هر طعم محصول و نوع ساخت ایجاد کنید، همچنین می‌توانید فهرست‌های منبع مجموعه را برای هر ترکیبی از طعم‌های محصول ایجاد کنید. به عنوان مثال، می‌توانید منابع جاوا را به دایرکتوری src/demoMinApi24/java/ ایجاد و اضافه کنید، و Gradle از این منابع فقط در هنگام ساختن گونه‌ای استفاده می‌کند که این دو طعم محصول را با هم ترکیب می‌کند.

مجموعه‌های منبعی که برای ترکیب طعم محصول ایجاد می‌کنید، اولویت بیشتری نسبت به مجموعه‌های منبعی دارند که به هر طعم محصول اختصاص دارند. برای کسب اطلاعات بیشتر درباره مجموعه‌های منبع و نحوه ادغام منابع Gradle، بخش نحوه ایجاد مجموعه‌های منبع را بخوانید.

انواع فیلتر

Gradle یک نوع ساخت برای هر ترکیب ممکن از طعم محصول و انواع ساختی که شما پیکربندی می کنید ایجاد می کند. با این حال، ممکن است انواع خاصی از ساخت وجود داشته باشد که شما به آنها نیاز ندارید یا در زمینه پروژه شما منطقی نیستند. برای حذف برخی از پیکربندی‌های نوع ساخت، یک فیلتر متغیر در فایل build.gradle.kts در سطح ماژول خود ایجاد کنید.

با استفاده از پیکربندی ساخت بخش قبلی به عنوان مثال، فرض کنید قصد دارید فقط سطوح API 23 و بالاتر را برای نسخه آزمایشی برنامه پشتیبانی کنید. می‌توانید از بلوک variantFilter برای فیلتر کردن تمام پیکربندی‌های نوع ساخت که ترکیبی از طعم‌های محصول «minApi21» و «demo» هستند استفاده کنید:

کاتلین

android {
  ...
  buildTypes {...}

  flavorDimensions += listOf("api", "mode")
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enable = false
        }
    }
}
...

شیار

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

هنگامی که یک فیلتر متغیر را به پیکربندی ساخت خود اضافه می‌کنید و روی همگام‌سازی اکنون در نوار اعلان کلیک می‌کنید، Gradle هر نوع ساختی را که شرایطی را که شما مشخص کرده‌اید برآورده می‌کند نادیده می‌گیرد. وقتی روی Build > انتخاب نوع ساخت از نوار منو یا Build Variants کلیک می کنید، دیگر در منو ظاهر نمی شود. در نوار پنجره ابزار

مجموعه های منبع ایجاد کنید

به طور پیش‌فرض، Android Studio مجموعه main/ منبع و دایرکتوری‌ها را برای هر چیزی که می‌خواهید بین همه انواع ساخت خود به اشتراک بگذارید، ایجاد می‌کند. با این حال، می‌توانید مجموعه‌های منبع جدیدی ایجاد کنید تا دقیقاً کنترل کنید که Gradle کدام فایل‌ها را کامپایل و بسته‌بندی می‌کند برای انواع ساخت‌های خاص، طعم‌های محصول، ترکیب طعم‌های محصول (هنگام استفاده از ابعاد طعم )، و انواع ساخت.

به عنوان مثال، می‌توانید عملکرد اصلی را در مجموعه main/ منبع تعریف کنید و از مجموعه‌های منبع طعم محصول برای تغییر نام تجاری برنامه خود برای مشتریان مختلف استفاده کنید، یا مجوزهای ویژه و عملکرد گزارش‌گیری را فقط برای انواع ساخت‌هایی که از نوع ساخت اشکال‌زدایی استفاده می‌کنند، بگنجانید.

Gradle انتظار دارد که فایل‌ها و دایرکتوری‌های مجموعه منبع به روشی خاص، مشابه مجموعه main/ منبع سازماندهی شوند. به عنوان مثال، Gradle انتظار دارد فایل‌های کلاس Kotlin یا Java که مخصوص نوع ساخت «debug» شما هستند در فهرست‌های src/debug/kotlin/ یا src/debug/java/ قرار گیرند.

افزونه Android Gradle یک کار مفید Gradle را ارائه می دهد که به شما نشان می دهد چگونه فایل های خود را برای هر یک از انواع ساخت، طعم محصول و انواع ساخت خود سازماندهی کنید. به عنوان مثال، نمونه زیر از خروجی وظیفه توضیح می دهد که Gradle انتظار دارد فایل های خاصی را برای نوع ساخت "debug" پیدا کند:

------------------------------------------------------------
Project :app
------------------------------------------------------------

...

debug
----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

برای مشاهده این خروجی به صورت زیر عمل کنید:

  1. روی Gradle در نوار پنجره ابزار کلیک کنید.
  2. به MyApplication > Tasks > android بروید و روی sourceSets دوبار کلیک کنید.

    برای دیدن پوشه Tasks ، باید به Gradle اجازه دهید تا لیست وظایف را در حین همگام سازی بسازد. برای انجام این کار، این مراحل را دنبال کنید:

    1. روی File > Settings > Experimental ( Android Studio > Settings > Experimental on macOS) کلیک کنید.
    2. در حین همگام سازی Gradle، لیست وظایف Gradle ایجاد نشود را لغو انتخاب کنید.
  3. بعد از اینکه Gradle وظیفه را اجرا کرد، پنجره Run برای نمایش خروجی باز می شود.

توجه: خروجی وظیفه همچنین به شما نشان می‌دهد که چگونه مجموعه‌های منبع را برای فایل‌هایی که می‌خواهید برای اجرای آزمایش‌های برنامه خود استفاده کنید، مانند مجموعه‌های منبع test/ و androidTest/ آزمایش سازماندهی کنید.

هنگامی که یک نوع ساخت جدید ایجاد می کنید، Android Studio دایرکتوری های مجموعه منبع را برای شما ایجاد نمی کند، اما چند گزینه برای کمک به شما در اختیار شما قرار می دهد. به عنوان مثال، برای ایجاد فقط دایرکتوری java/ برای نوع ساخت "debug" خود:

  1. پنجره Project را باز کنید و نمای پروژه را از منوی بالای صفحه انتخاب کنید.
  2. به MyProject/app/src/ بروید.
  3. روی دایرکتوری src کلیک راست کرده و New > Directory را انتخاب کنید.
  4. از منوی Gradle Source Sets ، full/java را انتخاب کنید.
  5. Enter را فشار دهید.

اندروید استودیو یک دایرکتوری مجموعه منبع برای نوع ساخت اشکال زدایی شما ایجاد می کند و سپس دایرکتوری java/ را در داخل آن ایجاد می کند. از طرف دیگر، Android Studio می تواند زمانی که یک فایل جدید را برای یک نوع ساخت خاص به پروژه خود اضافه می کنید، دایرکتوری ها را برای شما ایجاد کند.

به عنوان مثال، برای ایجاد یک فایل XML مقادیر برای نوع ساخت "debug" خود:

  1. در پنجره Project ، روی دایرکتوری src کلیک راست کرده و New > XML > Values ​​XML File را انتخاب کنید.
  2. نام فایل XML را وارد کنید یا نام پیش فرض را نگه دارید.
  3. از منوی کنار Target Source Set ، debug را انتخاب کنید.
  4. روی Finish کلیک کنید.

از آنجایی که نوع ساخت «اشکال‌زدایی» به‌عنوان مجموعه منبع هدف مشخص شده بود، Android Studio به‌طور خودکار فهرست‌های لازم را هنگام ایجاد فایل XML ایجاد می‌کند. ساختار دایرکتوری حاصل مانند شکل 1 است.

شکل 1. دایرکتوری های مجموعه منبع جدید برای نوع ساخت "debug".

مجموعه های منبع فعال دارای یک نشانگر سبز رنگ در نماد خود هستند تا نشان دهند که فعال هستند. مجموعه منبع debug با پسوند [main] اضافه می شود تا نشان دهد که در مجموعه منبع main ادغام خواهد شد.

با استفاده از همین رویه، همچنین می‌توانید فهرست‌های منبع مجموعه‌ای را برای طعم‌های محصول، مانند src/demo/ ، و انواع ساخت، مانند src/demoDebug/ ایجاد کنید. علاوه بر این، می‌توانید مجموعه‌های منبع آزمایشی ایجاد کنید که انواع ساخت‌های خاص را هدف قرار می‌دهند، مانند src/androidTestDemoDebug/ . برای کسب اطلاعات بیشتر، درباره تست مجموعه های منبع مطالعه کنید.

تنظیمات پیش فرض مجموعه منبع را تغییر دهید

اگر منابعی دارید که در ساختار فایل مجموعه منبع پیش‌فرض سازماندهی نشده‌اند که Gradle انتظار دارد، همانطور که در بخش قبلی درباره ایجاد مجموعه‌های منبع توضیح داده شد، می‌توانید از بلوک sourceSets برای تغییر مکان ظاهری Gradle برای جمع‌آوری فایل‌ها برای هر جزء از یک منبع استفاده کنید. مجموعه

بلوک sourceSets باید در بلوک android باشد. شما نیازی به تغییر مکان فایل های منبع ندارید. شما فقط باید مسیر(های) را نسبت به فایل build.gradle.kts سطح ماژول در اختیار Gradle قرار دهید، جایی که Gradle می‌تواند فایل‌ها را برای هر جزء مجموعه منبع پیدا کند. برای اینکه بدانید کدام مؤلفه‌ها را می‌توانید پیکربندی کنید و آیا می‌توانید آنها را به چندین فایل یا فهرست راهنما نگاشت کنید، به مرجع API افزونه Android Gradle مراجعه کنید.

نمونه کد زیر منابع را از دایرکتوری app/other/ به اجزای خاصی از مجموعه منبع main نگاشت و دایرکتوری ریشه مجموعه منبع androidTest را تغییر می دهد:

کاتلین

android {
  ...
  // Encapsulates configurations for the main source set.
  sourceSets.getByName("main") {
    // Changes the directory for Java sources. The default directory is
    // 'src/main/java'.
    java.setSrcDirs(listOf("other/java"))

    // If you list multiple directories, Gradle uses all of them to collect
    // sources. Because Gradle gives these directories equal priority, if
    // you define the same resource in more than one directory, you receive an
    // error when merging resources. The default directory is 'src/main/res'.
    res.setSrcDirs(listOf("other/res1", "other/res2"))

    // Note: Avoid specifying a directory that is a parent to one
    // or more other directories you specify. For example, avoid the following:
    // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
    // Specify either only the root 'other/res1' directory or only the
    // nested 'other/res1/layouts' and 'other/res1/strings' directories.

    // For each source set, you can specify only one Android manifest.
    // By default, Android Studio creates a manifest for your main source
    // set in the src/main/ directory.
    manifest.srcFile("other/AndroidManifest.xml")
    ...
  }

  // Create additional blocks to configure other source sets.
  sourceSets.getByName("androidTest") {
      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
  }
}
...

شیار

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // If you list multiple directories, Gradle uses all of them to collect
      // sources. Because Gradle gives these directories equal priority, if
      // you define the same resource in more than one directory, you receive an
      // error when merging resources. The default directory is 'src/main/res'.
      res.srcDirs = ['other/res1', 'other/res2']

      // Note: Avoid specifying a directory that is a parent to one
      // or more other directories you specify. For example, avoid the following:
      // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
      // Specify either only the root 'other/res1' directory or only the
      // nested 'other/res1/layouts' and 'other/res1/strings' directories.

      // For each source set, you can specify only one Android manifest.
      // By default, Android Studio creates a manifest for your main source
      // set in the src/main/ directory.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

توجه داشته باشید که دایرکتوری منبع فقط می تواند به یک مجموعه منبع تعلق داشته باشد. برای مثال، نمی‌توانید منابع آزمایشی یکسانی را با مجموعه‌های منبع test و androidTest به اشتراک بگذارید. این به این دلیل است که Android Studio ماژول های IntelliJ جداگانه برای هر مجموعه منبع ایجاد می کند و نمی تواند از ریشه های محتوای تکراری در مجموعه های منبع پشتیبانی کند.

ساخت با مجموعه های منبع

شما می توانید از دایرکتوری های مجموعه منبع استفاده کنید تا حاوی کد و منابعی باشد که می خواهید فقط با تنظیمات خاصی بسته بندی شوند. به عنوان مثال، اگر شما در حال ساخت نوع "demoDebug" هستید که محصول متقاطع طعم محصول "دمو" و نوع ساخت "debug" است، Gradle به این دایرکتوری ها نگاه می کند و اولویت زیر را به آنها می دهد:

  1. src/demoDebug/ (مجموعه منبع نوع ساخت)
  2. src/debug/ (مجموعه منبع نوع ساخت)
  3. src/demo/ (مجموعه منبع طعم محصول)
  4. src/main/ (مجموعه منبع اصلی)

مجموعه های منبع ایجاد شده برای ترکیبی از طعم های محصول باید شامل تمام ابعاد طعم باشد. به عنوان مثال، مجموعه منبع نوع ساخت باید ترکیبی از نوع ساخت و تمام ابعاد طعم باشد. ادغام کد و منابعی که شامل پوشه‌هایی می‌شود که چندین ابعاد را پوشش می‌دهند اما همه ابعاد طعم را پوشش نمی‌دهند، پشتیبانی نمی‌شود.

اگر چندین طعم محصول را ترکیب کنید ، اولویت بین طعم های محصول با توجه به بعد طعمی که به آن تعلق دارند تعیین می شود. هنگام فهرست‌بندی ابعاد طعم با ویژگی android.flavorDimensions ، طعم‌های محصولی که به بعد طعم اولی که فهرست می‌کنید، اولویت بیشتری نسبت به طعم‌های متعلق به بعد طعم دوم دارند و غیره. علاوه بر این، مجموعه‌های منبعی که برای ترکیبی از طعم‌های محصول ایجاد می‌کنید، اولویت بیشتری نسبت به مجموعه‌های منبعی دارند که به طعم محصول جداگانه تعلق دارند.

ترتیب اولویت تعیین می‌کند که وقتی Gradle کد و منابع را ترکیب می‌کند، کدام مجموعه منبع اولویت بیشتری دارد. از آنجایی که دایرکتوری demoDebug/ source set احتمالا حاوی فایل هایی است که مختص آن نوع ساخت هستند، اگر demoDebug/ شامل فایلی باشد که در debug/ نیز تعریف شده است، Gradle از فایل در مجموعه منبع demoDebug/ استفاده می کند. به طور مشابه، Gradle به فایل‌ها در نوع ساخت و منبع طعم محصول اولویت بیشتری نسبت به فایل‌های مشابه در main/ می‌دهد. Gradle این ترتیب اولویت را هنگام اعمال قوانین ساخت زیر در نظر می گیرد:

  • تمام کدهای منبع در دایرکتوری های kotlin/ یا java/ با هم کامپایل می شوند تا یک خروجی واحد تولید کنند.

    توجه: برای یک نوع ساخت معین، Gradle در صورتی که با دو یا چند دایرکتوری مجموعه منبع مواجه شود که یک کلاس Kotlin یا Java را تعریف کرده اند، یک خطای ساخت ایجاد می کند. به عنوان مثال، هنگام ساختن یک برنامه اشکال زدایی، نمی توانید هم src/debug/Utility.kt و هم src/main/Utility.kt تعریف کنید، زیرا Gradle در طول فرآیند ساخت به هر دو این دایرکتوری ها نگاه می کند و خطای "کلاس تکراری" می دهد. . اگر نسخه‌های مختلف Utility.kt را برای انواع ساخت‌های مختلف می‌خواهید، هر نوع ساخت باید نسخه خود را از فایل تعریف کند و آن را در مجموعه main/ منبع گنجانده نشود.

  • مانیفست ها در یک مانیفست واحد با هم ادغام می شوند. اولویت به همان ترتیب لیست در مثال قبلی داده شده است. یعنی تنظیمات مانیفست برای یک نوع ساخت، تنظیمات مانیفست برای طعم محصول و غیره را لغو می کند. برای کسب اطلاعات بیشتر، درباره ادغام مانیفست بخوانید.
  • فایل های موجود در values/ دایرکتوری ها با هم ادغام می شوند. اگر دو فایل نام یکسانی داشته باشند، مانند دو فایل strings.xml ، اولویت به همان ترتیب لیست در مثال قبلی داده می شود. یعنی مقادیر تعریف شده در یک فایل در مجموعه منبع نوع ساخت، مقادیر تعریف شده در همان فایل در طعم محصول و غیره را لغو می کنند.
  • منابع موجود در دایرکتوری های res/ و asset/ با هم بسته بندی می شوند. اگر منابعی با نام یکسان در دو یا چند مجموعه منبع تعریف شده باشد، اولویت به همان ترتیب لیست در مثال قبلی داده می شود.
  • Gradle به منابع و مانیفست های موجود در وابستگی های ماژول کتابخانه کمترین اولویت را هنگام ساخت برنامه می دهد.

وابستگی ها را اعلام کنید

برای پیکربندی یک وابستگی برای یک نوع ساخت خاص یا مجموعه منبع آزمایشی ، پیشوند نام نوع ساخت یا مجموعه منبع آزمایشی را قبل از کلمه کلیدی Implementation قرار دهید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    "freeImplementation"(project(":mylibrary"))

    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}

شیار

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    freeImplementation project(":mylibrary")

    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

برای اطلاعات بیشتر درباره پیکربندی وابستگی‌ها، به افزودن وابستگی‌های ساخت مراجعه کنید.

از مدیریت وابستگی آگاهانه استفاده کنید

افزونه Android Gradle نسخه 3.0.0 و بالاتر شامل یک مکانیسم وابستگی جدید است که به طور خودکار انواع را هنگام مصرف یک کتابخانه مطابقت می دهد. این به این معنی است که نوع debug یک برنامه به طور خودکار نوع debug یک کتابخانه و غیره را مصرف می کند. همچنین هنگام استفاده از طعم‌ها کار می‌کند: نوع freeDebug یک برنامه، نوع freeDebug یک کتابخانه را مصرف می‌کند.

برای اینکه این افزونه به طور دقیق با انواع مختلف مطابقت داشته باشد، باید بک گراندهای منطبق را همانطور که در بخش زیر توضیح داده شده است ارائه دهید ، برای نمونه هایی که تطبیق مستقیم امکان پذیر نیست.

به عنوان مثال، فرض کنید برنامه شما یک نوع ساخت به نام "staging" را پیکربندی می کند، اما یکی از وابستگی های کتابخانه آن این کار را نمی کند. وقتی افزونه سعی می‌کند نسخه «staging» برنامه شما را بسازد، نمی‌داند از کدام نسخه کتابخانه استفاده کند و یک پیام خطایی شبیه به زیر مشاهده می‌کنید:

Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
    project :app

خطاهای ساخت مربوط به تطبیق انواع را حل کنید

این افزونه شامل عناصر DSL است تا به شما کمک کند نحوه حل و فصل موقعیت‌هایی را که در آن‌ها تطبیق نوع مستقیم بین یک برنامه و یک وابستگی امکان‌پذیر نیست را کنترل کنید.

در زیر فهرستی از مسائل مربوط به تطبیق وابستگی با نوع آگاه و نحوه حل آنها با استفاده از ویژگی های DSL آمده است:

  • برنامه شما دارای یک نوع ساخت است که وابستگی کتابخانه آن را ندارد.

    به عنوان مثال، برنامه شما شامل یک نوع ساخت "staging" است، اما یک وابستگی فقط شامل انواع ساخت "debug" و "release" است.

    توجه داشته باشید که وقتی وابستگی کتابخانه شامل یک نوع ساخت است که برنامه شما ندارد، مشکلی وجود ندارد. دلیلش این است که پلاگین هرگز آن نوع ساخت را از وابستگی درخواست نمی کند.

    همانطور که در اینجا نشان داده شده است، از matchingFallbacks برای تعیین موارد مشابه برای یک نوع ساخت معین استفاده کنید:

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        buildTypes {
            getByName("debug") {}
            getByName("release") {}
            create("staging") {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks += listOf("debug", "qa", "release")
            }
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
  • برای یک بعد طعم معین که هم در برنامه و هم در وابستگی کتابخانه آن وجود دارد، برنامه شما شامل طعم هایی است که کتابخانه آن را ندارد.

    به عنوان مثال، هم برنامه شما و هم وابستگی های کتابخانه آن دارای یک بعد طعم "سطح" هستند. با این حال، بعد "سطح" در برنامه شامل طعم های "رایگان" و "پرداخت" است، اما یک وابستگی فقط شامل طعم های "دمو" و "پرداخت" برای همان بعد است.

    توجه داشته باشید که برای یک بعد طعم معین که هم در برنامه و هم در وابستگی‌های کتابخانه آن وجود دارد، زمانی که یک کتابخانه دارای طعم محصولی باشد که برنامه شما ندارد، مشکلی وجود ندارد. دلیلش این است که پلاگین هرگز آن طعم را از وابستگی درخواست نمی کند.

    همانطور که در اینجا نشان داده شده است، از matchingFallbacks برای تعیین موارد مشابه برای طعم محصول "رایگان" برنامه استفاده کنید:

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions += "tier"
        productFlavors {
            create("paid") {
                dimension = "tier"
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            create("free") {
                dimension = "tier"
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks += listOf("demo", "trial")
            }
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
  • وابستگی کتابخانه شامل یک بعد طعم است که برنامه شما ندارد.

    برای مثال، یک وابستگی کتابخانه شامل طعم‌هایی برای بعد «minApi» است، اما برنامه شما شامل طعم‌هایی فقط برای بعد «سطح» است. وقتی می‌خواهید نسخه «freeDebug» برنامه خود را بسازید، افزونه نمی‌داند که از نسخه «minApi23Debug» یا «minApi18Debug» وابستگی استفاده کند.

    توجه داشته باشید که زمانی که برنامه شما دارای یک بعد طعم باشد، مشکلی وجود ندارد که وابستگی کتابخانه آن را ندارد. دلیل آن این است که این افزونه فقط با ابعادی که در وابستگی وجود دارد مطابقت دارد. به عنوان مثال، اگر یک وابستگی شامل یک بعد برای ABI ها نباشد، نسخه "freeX86Debug" برنامه شما از نسخه "freeDebug" وابستگی استفاده می کند.

    همانطور که در نمونه زیر نشان داده شده است، از missingDimensionStrategy در بلوک defaultConfig استفاده کنید تا طعم پیش فرض را برای افزونه برای انتخاب از هر بعد گمشده مشخص کنید. همچنین می‌توانید انتخاب‌های خود را در بلوک productFlavors لغو کنید، بنابراین هر طعم می‌تواند استراتژی تطبیقی ​​متفاوتی را برای بعد گمشده مشخص کند.

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy("minApi", "minApi18", "minApi23")
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy("abi", "x86", "arm64")
        }
        flavorDimensions += "tier"
        productFlavors {
            create("free") {
                dimension = "tier"
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy("minApi", "minApi23", "minApi18")
            }
            create("paid") {}
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the 'minApi' dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }

برای اطلاعات بیشتر، matchingFallbacks و missingDimensionStrategy در مرجع DSL پلاگین Android Gradle ببینید.

تنظیمات امضا را پیکربندی کنید

Gradle APK یا AAB ساخت نسخه شما را امضا نمی‌کند مگر اینکه صریحاً یک پیکربندی امضا برای این ساخت تعریف کنید. اگر هنوز کلید امضا ندارید، یک کلید آپلود و ذخیره کلید با استفاده از Android Studio ایجاد کنید .

برای پیکربندی دستی پیکربندی های امضا برای نوع ساخت نسخه خود با استفاده از تنظیمات ساخت Gradle:

  1. یک فروشگاه کلید ایجاد کنید. انبار کلید یک فایل باینری است که شامل مجموعه ای از کلیدهای خصوصی است. شما باید فروشگاه کلید خود را در مکانی امن و مطمئن نگه دارید.
  2. یک کلید خصوصی ایجاد کنید. یک کلید خصوصی برای امضای برنامه شما برای توزیع استفاده می‌شود و هرگز همراه برنامه نیست و در اختیار اشخاص ثالث غیرمجاز قرار نمی‌گیرد.
  3. پیکربندی امضا را به فایل build.gradle.kts در سطح ماژول اضافه کنید:

    کاتلین

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

    شیار

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

توجه: گنجاندن گذرواژه‌های کلید انتشار و ذخیره‌سازی کلید در داخل فایل ساخت، عمل امنیتی خوبی نیست. درعوض، فایل ساخت را طوری پیکربندی کنید که این پسوردها را از متغیرهای محیطی دریافت کند یا فرآیند ساخت را از شما بخواهد که این پسوردها را دریافت کنید.

برای بدست آوردن این رمزهای عبور از متغیرهای محیطی:

کاتلین

storePassword = System.getenv("KSTOREPWD")
keyPassword = System.getenv("KEYPWD")

شیار

storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

همچنین، می‌توانید keystore را از یک فایل ویژگی‌های محلی بارگیری کنید. به دلایل امنیتی، این فایل را به کنترل منبع اضافه نکنید. در عوض، آن را به صورت محلی برای هر توسعه دهنده تنظیم کنید. برای کسب اطلاعات بیشتر، حذف اطلاعات امضا از فایل‌های ساخت خود را بخوانید.

پس از تکمیل این فرآیند، می توانید برنامه خود را توزیع کرده و آن را در Google Play منتشر کنید.

اخطار: فروشگاه کلید و کلید خصوصی خود را در مکانی امن و مطمئن نگه دارید و مطمئن شوید که پشتیبان امنی از آنها دارید. اگر از Play App Signing استفاده می‌کنید و کلید آپلود خود را گم می‌کنید، می‌توانید با استفاده از Play Console درخواست بازنشانی کنید . اگر برنامه‌ای را بدون Play App Signing منتشر می‌کنید (برای برنامه‌هایی که قبل از آگوست 2021 ایجاد شده‌اند) و کلید امضای برنامه خود را از دست می‌دهید، نمی‌توانید هیچ به‌روزرسانی برای برنامه خود منتشر کنید، زیرا همیشه باید همه نسخه‌های برنامه خود را با همان کلید

امضای برنامه‌های Wear OS

هنگام انتشار برنامه‌های Wear OS، APK ساعت و APK اختیاری تلفن باید با یک کلید امضا شوند. برای اطلاعات بیشتر درباره بسته‌بندی و امضای برنامه‌های Wear OS، به بسته‌بندی و توزیع برنامه‌های Wear مراجعه کنید.

،

این صفحه به شما نشان می دهد که چگونه می توانید انواع ساخت را برای ایجاد نسخه های مختلف برنامه خود از یک پروژه واحد پیکربندی کنید و چگونه وابستگی ها و پیکربندی های امضای خود را به درستی مدیریت کنید.

هر نوع ساخت نشان دهنده نسخه متفاوتی از برنامه شما است که می توانید بسازید. به عنوان مثال، ممکن است بخواهید یک نسخه از برنامه خود را بسازید که رایگان با مجموعه ای محدود از محتوا، و نسخه دیگری پولی که شامل موارد بیشتری باشد. همچنین می‌توانید نسخه‌های مختلفی از برنامه خود را بسازید که دستگاه‌های مختلف را هدف قرار می‌دهند، بر اساس سطح API یا سایر تغییرات دستگاه.

انواع ساخت نتیجه استفاده Gradle از مجموعه ای خاص از قوانین برای ترکیب تنظیمات، کد و منابع پیکربندی شده در انواع ساخت و طعم محصول شماست. اگرچه شما انواع ساخت را مستقیماً پیکربندی نمی‌کنید، اما انواع ساخت و طعم‌های محصول را که آنها را تشکیل می‌دهند پیکربندی می‌کنید.

برای مثال، طعم محصول «دمو» ممکن است ویژگی‌ها و الزامات دستگاه را مشخص کند، مانند کد منبع سفارشی، منابع، و حداقل سطوح API، در حالی که نوع ساخت «اشکال‌زدایی» تنظیمات مختلف ساخت و بسته‌بندی، مانند گزینه‌های اشکال‌زدایی و امضا را اعمال می‌کند. کلیدها نوع ساختی که این دو را ترکیب می‌کند، نسخه «demoDebug» برنامه شما است و ترکیبی از پیکربندی‌ها و منابع موجود در طعم محصول «دمو»، نوع ساخت «اشکال‌زدایی» و مجموعه main/ منبع را شامل می‌شود.

پیکربندی انواع ساخت

می توانید انواع ساخت را در بلوک android فایل build.gradle.kts در سطح ماژول ایجاد و پیکربندی کنید. هنگامی که یک ماژول جدید ایجاد می کنید، Android Studio به طور خودکار انواع ساخت دیباگ و انتشار را ایجاد می کند. اگرچه نوع ساخت اشکال‌زدایی در فایل پیکربندی ساخت ظاهر نمی‌شود، Android Studio آن را با debuggable true پیکربندی می‌کند. این به شما امکان می‌دهد برنامه را در دستگاه‌های Android ایمن اشکال‌زدایی کنید و امضای برنامه را با یک فروشگاه کلید اشکال زدایی عمومی پیکربندی کنید.

اگر می‌خواهید تنظیمات خاصی را اضافه یا تغییر دهید، می‌توانید نوع ساخت اشکال‌زدایی را به پیکربندی خود اضافه کنید. نمونه زیر یک applicationIdSuffix برای نوع ساخت اشکال‌زدایی مشخص می‌کند و یک نوع ساخت «staging» را پیکربندی می‌کند که با استفاده از تنظیمات از نوع ساخت اشکال‌زدایی مقداردهی اولیه می‌شود:

کاتلین

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
        ...
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }

        getByName("debug") {
            applicationIdSuffix = ".debug"
            isDebuggable = true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        create("staging") {
            initWith(getByName("debug"))
            manifestPlaceholders["hostName"] = "internal.example.com"
            applicationIdSuffix = ".debugStaging"
        }
    }
}

شیار

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
        ...
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
            debuggable true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix ".debugStaging"
        }
    }
}

توجه: هنگامی که در فایل پیکربندی ساخت، تغییراتی ایجاد می کنید، Android Studio از شما می خواهد که پروژه خود را با پیکربندی جدید همگام سازی کنید. برای همگام سازی پروژه خود، روی همگام سازی اکنون در نوار اعلان که هنگام ایجاد تغییر ظاهر می شود کلیک کنید یا روی همگام سازی پروژه کلیک کنید. از نوار ابزار اگر Android Studio متوجه هر گونه خطایی در پیکربندی شما شود، پنجره Messages برای توصیف مشکل ظاهر می شود.

برای کسب اطلاعات بیشتر در مورد تمام ویژگی هایی که می توانید با انواع ساخت پیکربندی کنید، مرجع BuildType را بخوانید.

طعم های محصول را پیکربندی کنید

ایجاد طعم محصول مشابه ایجاد انواع ساخت است. طعم های محصول را به بلوک productFlavors در پیکربندی ساخت خود اضافه کنید و تنظیماتی را که می خواهید اضافه کنید. طعم های محصول از ویژگی های defaultConfig پشتیبانی می کنند، زیرا defaultConfig در واقع به کلاس ProductFlavor تعلق دارد. این بدان معناست که می‌توانید پیکربندی پایه را برای همه طعم‌ها در بلوک defaultConfig ارائه کنید و هر طعم می‌تواند هر یک از این مقادیر پیش‌فرض را تغییر دهد، مانند applicationId . برای کسب اطلاعات بیشتر در مورد شناسه برنامه، تنظیم شناسه برنامه را بخوانید.

توجه: همچنان باید نام بسته را با استفاده از ویژگی package در فایل main/ مانیفست مشخص کنید. همچنین باید از آن نام بسته در کد منبع خود برای ارجاع به کلاس R یا حل هر گونه فعالیت یا ثبت خدمات نسبی استفاده کنید. این به شما امکان می دهد از applicationId استفاده کنید تا به هر محصول یک شناسه منحصر به فرد برای بسته بندی و توزیع بدون نیاز به تغییر کد منبع خود بدهید.

همه طعم ها باید به یک بعد طعم نامگذاری شده تعلق داشته باشند که گروهی از طعم های محصول است. شما باید همه طعم ها را به یک بعد طعم اختصاص دهید. در غیر این صورت با خطای ساخت زیر مواجه خواهید شد.

  Error: All flavors must now belong to a named flavor dimension.
  The flavor 'flavor_name' is not assigned to a flavor dimension.

اگر یک ماژول معین فقط یک بعد طعم را مشخص کند، افزونه Android Gradle به طور خودکار همه طعم‌های ماژول را به آن بعد اختصاص می‌دهد.

نمونه کد زیر یک بعد طعم به نام "نسخه" ایجاد می کند و طعم های "دمو" و "کامل" محصول را اضافه می کند. این طعم ها applicationIdSuffix و versionNameSuffix خود را ارائه می دهند:

کاتلین

android {
    ...
    defaultConfig {...}
    buildTypes {
        getByName("debug"){...}
        getByName("release"){...}
    }
    // Specifies one flavor dimension.
    flavorDimensions += "version"
    productFlavors {
        create("demo") {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension = "version"
            applicationIdSuffix = ".demo"
            versionNameSuffix = "-demo"
        }
        create("full") {
            dimension = "version"
            applicationIdSuffix = ".full"
            versionNameSuffix = "-full"
        }
    }
}

شیار

android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

توجه: اگر برنامه قدیمی دارید (که قبل از آگوست 2021 ایجاد شده است) که با استفاده از APK ها در Google Play توزیع می کنید، برای توزیع برنامه خود با استفاده از پشتیبانی از چندین APK در Google Play، یک مقدار applicationId یکسان را به همه گونه ها اختصاص دهید و به هر گونه یک versionCode متفاوت بدهید. . برای توزیع انواع مختلف برنامه خود به عنوان برنامه های جداگانه در Google Play، باید یک applicationId متفاوت به هر گونه اختصاص دهید.

پس از ایجاد و پیکربندی طعم های محصول خود، روی همگام سازی اکنون در نوار اعلان کلیک کنید. هنگامی که همگام سازی کامل شد، Gradle به طور خودکار انواع ساخت را بر اساس نوع ساخت و طعم محصول شما ایجاد می کند و آنها را بر اساس <product-flavor><Build-Type> نام گذاری می کند. به عنوان مثال، اگر طعم های محصول "دمو" و "کامل" را ایجاد کرده باشید و انواع ساخت پیش فرض "debug" و "release" را حفظ کرده باشید، Gradle انواع ساخت زیر را ایجاد می کند:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

برای انتخاب نوع ساخت و اجرا، به Build > Select Build Variant بروید و یک نوع ساخت را از منو انتخاب کنید. برای شروع سفارشی‌سازی هر نوع ساخت با ویژگی‌ها و منابع خاص خود، باید مجموعه‌های منبع را ایجاد و مدیریت کنید ، همانطور که در این صفحه توضیح داده شده است.

شناسه برنامه را برای انواع ساخت تغییر دهید

هنگامی که یک برنامه APK یا AAB را برای برنامه خود می سازید ، Build Tools برنامه را با شناسه برنامه تعریف شده در بلوک defaultConfig از پرونده build.gradle.kts ، همانطور که در مثال زیر نشان داده شده است ، برچسب گذاری می کنند. با این حال ، اگر می خواهید نسخه های مختلفی از برنامه خود را ایجاد کنید تا به عنوان لیست های جداگانه در فروشگاه Google Play ، مانند نسخه "رایگان" و "Pro" ظاهر شود ، باید انواع ساخت و ساز جداگانه ای ایجاد کنید که هر یک دارای شناسه کاربردی متفاوتی هستند.

در این حالت ، هر نوع ساخت را به عنوان یک طعم محصول جداگانه تعریف کنید. برای هر عطر و طعم موجود در بلوک productFlavors ، می توانید ویژگی applicationId را دوباره تعریف کنید ، یا در عوض می توانید یک بخش را با استفاده از applicationIdSuffix به شناسه برنامه پیش فرض اضافه کنید ، همانطور که در اینجا نشان داده شده است:

کاتلین

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
        }
    }
}

شیار

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        pro {
            applicationIdSuffix ".pro"
        }
    }
}

به این ترتیب ، شناسه برنامه برای طعم محصول "رایگان" "com.example.myapp.free" است.

همچنین می توانید از applicationIdSuffix برای اضافه کردن یک بخش بر اساس نوع ساخت خود استفاده کنید ، همانطور که در اینجا نشان داده شده است:

کاتلین

android {
    ...
    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
        }
    }
}

شیار

android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

از آنجا که Gradle پیکربندی نوع ساخت را پس از طعم محصول اعمال می کند ، شناسه برنامه برای نوع ساخت "اشکال زدایی رایگان" "com.example.myapp.free.debug" است. این زمانی مفید است که شما می خواهید هر دو اشکال زدایی و انتشار را در همان دستگاه ایجاد کنید ، زیرا هیچ دو برنامه نمی توانند شناسه برنامه یکسان داشته باشند.

اگر یک برنامه Legacy دارید (قبل از اوت 2021 ایجاد شده است) که با استفاده از APK ها در Google Play توزیع می کنید ، و می خواهید از همان لیست برنامه برای توزیع چندین APK استفاده کنید که هر یک از آنها پیکربندی دستگاه متفاوتی مانند سطح API را هدف قرار می دهد ، سپس شما برای هر نوع ساخت باید از همان شناسه برنامه استفاده کنید اما به هر APK versionCode دیگری را بدهید. برای اطلاعات بیشتر ، در مورد پشتیبانی از APK متعدد بخوانید. انتشار با استفاده از AABS بی تأثیر است ، زیرا از یک مصنوع واحد استفاده می کند که به طور پیش فرض از یک کد نسخه و شناسه برنامه استفاده می کند.

نکته: در صورت نیاز به مراجعه به شناسه برنامه در پرونده مانیفست خود ، می توانید در هر ویژگی مانیفست از محل نگهدارنده ${applicationId} استفاده کنید. در حین ساخت ، Gradle این برچسب را با شناسه برنامه واقعی جایگزین می کند. برای اطلاعات بیشتر ، به متغیرهای تزریق در مانیفست مراجعه کنید.

چندین طعم محصول را با ابعاد عطر و طعم ترکیب کنید

در بعضی موارد ، شما ممکن است بخواهید تنظیمات را از چندین طعم محصول ترکیب کنید. به عنوان مثال ، شما ممکن است بخواهید تنظیمات مختلفی را برای طعم های محصول "کامل" و "نسخه ی نمایشی" ایجاد کنید که مبتنی بر سطح API هستند. برای انجام این کار ، افزونه Android Gradle به شما امکان می دهد چندین گروه از طعم های محصول را به عنوان ابعاد طعم ایجاد کنید.

هنگام ساختن برنامه خود ، Gradle از هر ابعاد طعم دهنده ای که تعریف می کنید ، همراه با پیکربندی نوع ساخت ، یک پیکربندی عطر و طعم محصول را ترکیب می کند تا نوع ساخت نهایی را ایجاد کند. Gradle طعم دهنده های محصول را که متعلق به همان بعد طعم دهنده هستند ، ترکیب نمی کند.

نمونه کد زیر از ویژگی flavorDimensions برای ایجاد ابعاد عطر و طعم "حالت" برای گروه بندی طعم های محصول "کامل" و "نسخه ی نمایشی" و ابعاد عطر و طعم "API" برای گروه بندی تنظیمات طعم محصول بر اساس سطح API استفاده می کند.

کاتلین

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdk = 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.
      versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdk = 23
      versionCode = 20000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdk = 21
      versionCode = 10000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

شیار

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.

      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion 23
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

تعداد انواع ساخت و ساز درجه یک برابر با محصول تعداد طعم دهنده ها در هر بعد طعم و تعداد انواع ساختگی که پیکربندی می کنید برابر است. هنگامی که Gradle هر نوع ساخت و ساز یا مصنوعات مربوطه را نامگذاری می کند ، طعم دهنده های محصول متعلق به بعد طعم بالاتر با اولویت بالاتر ظاهر می شوند ، و به دنبال آن از ابعاد اولویت پایین تر و به دنبال آن نوع ساخت.

با استفاده از پیکربندی ساخت قبلی به عنوان نمونه ، Gradle در مجموع 12 نوع ساخت با طرح نامگذاری زیر ایجاد می کند:

  • ساخت نوع: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
  • APK مربوطه: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
  • به عنوان مثال،
    ساخت نوع: minApi24DemoDebug
    APK مربوطه: app-minApi24-demo-debug.apk

علاوه بر دایرکتوری های مجموعه منبع که می توانید برای هر محصول خاص و عطر و طعم ایجاد کنید ، می توانید برای هر ترکیبی از طعم دهنده های محصول ، دایرکتوری های مجموعه منبع ایجاد کنید. به عنوان مثال ، می توانید منابع جاوا را به src/demoMinApi24/java/ Directory ایجاد و اضافه کنید ، و Gradle فقط در هنگام ساختن یک نوع که ترکیب آن دو طعم محصول است ، از آن منابع استفاده می کند.

مجموعه منبع شما برای ترکیب عطر و طعم محصول از اولویت بالاتری نسبت به مجموعه های منبع که متعلق به هر عطر و طعم محصول جداگانه است ، دارند. برای کسب اطلاعات بیشتر در مورد مجموعه های منبع و چگونگی ادغام Gradle منابع ، بخش مربوط به نحوه ایجاد مجموعه های منبع را بخوانید.

انواع فیلتر

Gradle برای هر ترکیب ممکن از طعم دهنده های محصول یک نوع ساخت ایجاد می کند و انواع مختلفی را که پیکربندی می کنید ایجاد می کند. با این وجود ، ممکن است انواع خاصی از ساخت و ساز وجود داشته باشد که شما به آن احتیاج ندارید یا در زمینه پروژه خود معنی ندارد. برای حذف برخی از تنظیمات مختلف ساخت ، یک فیلتر build.gradle.kts را در پرونده سطح ماژول خود ایجاد کنید.

با استفاده از پیکربندی ساخت از بخش قبلی به عنوان نمونه ، فرض کنید قصد دارید فقط از سطح API 23 و بالاتر برای نسخه نسخه ی نمایشی برنامه پشتیبانی کنید. شما می توانید از بلوک variantFilter استفاده کنید تا تمام تنظیمات مختلف ساخت و ساز را که ترکیب "Minapi21" و "Demo" طعم دهنده محصول است ، فیلتر کنید:

کاتلین

android {
  ...
  buildTypes {...}

  flavorDimensions += listOf("api", "mode")
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enable = false
        }
    }
}
...

شیار

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

هنگامی که یک فیلتر متنوع را به پیکربندی ساخت خود اضافه می کنید و هم اکنون در نوار اعلان همگام سازی می کنید ، Gradle انواع مختلفی از ساخت و ساز را که شرایط تعیین شده را برآورده می کند ، نادیده می گیرد. انواع ساخت و ساز دیگر در منو وقتی کلیک می کنید BUILD> SELECT Build Variant را از نوار منو یا ساخت انواع ایجاد کنید در نوار پنجره ابزار.

مجموعه های منبع را ایجاد کنید

به طور پیش فرض ، Android Studio مجموعه main/ منبع و دایرکتوری ها را برای همه چیزهایی که می خواهید بین همه انواع ساخت خود به اشتراک بگذارید ، ایجاد می کند. با این حال ، شما می توانید مجموعه های منبع جدیدی ایجاد کنید تا دقیقاً کدام یک از ترکیبات و بسته های Gradle را برای انواع خاص ساخت ، طعم دهنده های محصول ، ترکیبی از طعم دهنده های محصول (هنگام استفاده از ابعاد طعم دهنده ) و ساخت انواع مختلف کنترل کنید.

به عنوان مثال ، شما می توانید عملکردهای اساسی را در مجموعه main/ منبع تعریف کنید و از مجموعه منبع عطر و طعم محصول استفاده کنید تا مارک تجاری برنامه خود را برای مشتری های مختلف تغییر دهید ، یا مجوزهای ویژه و عملکرد ورود به سیستم را فقط برای ساخت انواع مختلفی که از نوع ساخت اشکال استفاده می کنند ، درج کنید.

Gradle انتظار دارد پرونده ها و دایرکتوری ها را به روشی خاص ، مشابه مجموعه main/ منبع سازماندهی کنند. به عنوان مثال ، Gradle انتظار دارد پرونده های کلاس Kotlin یا Java که مخصوص نوع ساخت "اشکال زدایی" شما هستند که در src/debug/kotlin/ یا src/debug/java/ DIRETRIES قرار دارد.

افزونه Android Gradle یک کار Gradle مفید را ارائه می دهد که به شما نشان می دهد که چگونه می توانید پرونده های خود را برای هر یک از انواع ساخت ، طعم دهنده های محصول و ساخت انواع خود سازماندهی کنید. به عنوان مثال ، نمونه زیر از خروجی کار توصیف می کند که در آن گرادل انتظار دارد پرونده های خاصی را برای نوع ساخت "اشکال زدایی" پیدا کند:

------------------------------------------------------------
Project :app
------------------------------------------------------------

...

debug
----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

برای مشاهده این خروجی ، به شرح زیر ادامه دهید:

  1. روی Gradle در نوار پنجره ابزار کلیک کنید.
  2. به MyApplication> Tasks> Android و منابع دو کلیک بروید.

    برای دیدن پوشه وظایف ، باید به Gradle اجازه دهید لیست کار را در حین همگام سازی بسازد. برای انجام این کار، این مراحل را دنبال کنید:

    1. روی پرونده> تنظیمات> آزمایش ( استودیوی اندرویدی> تنظیمات> آزمایش در MACOS) کلیک کنید.
    2. DEELECT لیست کار Gradle را در طول همگام سازی Gradle ایجاد نکنید .
  3. پس از انجام Gradle کار ، پنجره Run برای نمایش خروجی باز می شود.

توجه: خروجی کار همچنین به شما نشان می دهد که چگونه می توانید مجموعه های منبع را برای پرونده هایی که می خواهید از آنها استفاده کنید برای اجرای تست های برنامه خود ، مانند مجموعه های test/ و androidTest/ تست ، سازماندهی کنید.

هنگامی که یک نوع ساخت جدید ایجاد می کنید ، Android Studio منبع مجموعه منبع را برای شما ایجاد نمی کند ، اما این گزینه برای کمک به شما چند گزینه به شما می دهد. به عنوان مثال ، برای ایجاد java/ Directory برای نوع ساخت "اشکال زدایی" خود:

  1. صفحه پروژه را باز کنید و نمای پروژه را از منو در بالای صفحه انتخاب کنید.
  2. حرکت به MyProject/app/src/ .
  3. روی فهرست src راست کلیک کرده و Directory New > را انتخاب کنید.
  4. از منوی زیر مجموعه های منبع Gradle ، Full/Java را انتخاب کنید.
  5. Enter را فشار دهید.

Android Studio یک دایرکتوری مجموعه منبع را برای نوع ساخت اشکال ایجاد می کند و سپس java/ دایرکتوری را در داخل آن ایجاد می کند. از طرف دیگر ، Android Studio می تواند هنگام اضافه کردن یک پرونده جدید به پروژه خود برای یک نوع ساخت خاص ، دایرکتوری ها را برای شما ایجاد کند.

به عنوان مثال ، برای ایجاد یک فایل XML مقادیر برای نوع ساخت "اشکال زدایی" خود:

  1. در صفحه پروژه ، روی دایرکتوری src راست کلیک کرده و پرونده XML New > XML > مقادیر را انتخاب کنید.
  2. نام پرونده XML را وارد کنید یا نام پیش فرض را نگه دارید.
  3. از منوی کنار مجموعه منبع هدف ، Debug را انتخاب کنید.
  4. روی Finish کلیک کنید.

از آنجا که نوع ساخت "اشکال زدایی" به عنوان مجموعه منبع هدف مشخص شده است ، Android Studio هنگام ایجاد پرونده XML به طور خودکار دایرکتوری های لازم را ایجاد می کند. ساختار دایرکتوری حاصل مانند شکل 1 به نظر می رسد.

شکل 1. دایرکتوری های جدید منبع برای نوع ساخت "اشکال زدایی".

مجموعه های منبع فعال دارای یک نشانگر سبز در نماد خود هستند تا نشان دهند که آنها فعال هستند. مجموعه منبع debug با [main] پسوند می شود تا نشان دهد که در مجموعه منبع main ادغام خواهد شد.

با استفاده از همان روش ، می توانید دایرکتوری های مجموعه منبع را برای طعم دهنده های محصول مانند src/demo/ و ساخت انواع مختلفی مانند src/demoDebug/ ایجاد کنید. علاوه بر این ، شما می توانید مجموعه های منبع آزمایش را ایجاد کنید که انواع ساخت و سازهای خاص مانند src/androidTestDemoDebug/ را هدف قرار دهید. برای کسب اطلاعات بیشتر ، در مورد مجموعه های منبع آزمایش بخوانید.

تنظیمات تنظیم منبع پیش فرض را تغییر دهید

اگر منابعی دارید که در ساختار فایل پیش فرض تنظیم فایل که Gradle انتظار دارد ، سازماندهی نشده اند ، همانطور که در بخش قبلی در مورد ایجاد مجموعه های منبع توضیح داده شده است ، می توانید از بلوک sourceSets استفاده کنید تا جایی که Gradle به دنبال جمع آوری پرونده ها برای هر مؤلفه یک منبع است ، تغییر دهید مجموعه

بلوک sourceSets باید در بلوک android باشد. نیازی به جابجایی پرونده های منبع نیست. شما فقط باید مسیر (ها) را نسبت به پرونده module- build.gradle.kts در سطح ماژول فراهم کنید ، جایی که Gradle می تواند برای هر یک از مؤلفه های تنظیم شده منبع پرونده هایی پیدا کند. برای یادگیری کدام مؤلفه ها می توانید پیکربندی کنید و آیا می توانید آنها را در چندین پرونده یا دایرکتوری نقشه برداری کنید ، به مرجع API افزونه Android Gradle مراجعه کنید.

نمونه کد زیر منابع نقشه را از app/other/ دایرکتوری به برخی از مؤلفه های مجموعه منبع main نقشه می کند و فهرست اصلی مجموعه منبع androidTest را تغییر می دهد:

کاتلین

android {
  ...
  // Encapsulates configurations for the main source set.
  sourceSets.getByName("main") {
    // Changes the directory for Java sources. The default directory is
    // 'src/main/java'.
    java.setSrcDirs(listOf("other/java"))

    // If you list multiple directories, Gradle uses all of them to collect
    // sources. Because Gradle gives these directories equal priority, if
    // you define the same resource in more than one directory, you receive an
    // error when merging resources. The default directory is 'src/main/res'.
    res.setSrcDirs(listOf("other/res1", "other/res2"))

    // Note: Avoid specifying a directory that is a parent to one
    // or more other directories you specify. For example, avoid the following:
    // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
    // Specify either only the root 'other/res1' directory or only the
    // nested 'other/res1/layouts' and 'other/res1/strings' directories.

    // For each source set, you can specify only one Android manifest.
    // By default, Android Studio creates a manifest for your main source
    // set in the src/main/ directory.
    manifest.srcFile("other/AndroidManifest.xml")
    ...
  }

  // Create additional blocks to configure other source sets.
  sourceSets.getByName("androidTest") {
      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
  }
}
...

شیار

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // If you list multiple directories, Gradle uses all of them to collect
      // sources. Because Gradle gives these directories equal priority, if
      // you define the same resource in more than one directory, you receive an
      // error when merging resources. The default directory is 'src/main/res'.
      res.srcDirs = ['other/res1', 'other/res2']

      // Note: Avoid specifying a directory that is a parent to one
      // or more other directories you specify. For example, avoid the following:
      // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
      // Specify either only the root 'other/res1' directory or only the
      // nested 'other/res1/layouts' and 'other/res1/strings' directories.

      // For each source set, you can specify only one Android manifest.
      // By default, Android Studio creates a manifest for your main source
      // set in the src/main/ directory.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

توجه داشته باشید که یک فهرست منبع فقط می تواند متعلق به یک مجموعه منبع باشد. به عنوان مثال ، شما نمی توانید منابع تست مشابه را با مجموعه های منبع test و androidTest به اشتراک بگذارید. این امر به این دلیل است که Android Studio ماژول های جداگانه IntelliJ را برای هر مجموعه منبع ایجاد می کند و نمی تواند ریشه های محتوای تکراری را در مجموعه های منبع پشتیبانی کند.

با مجموعه های منبع بسازید

شما می توانید از دایرکتوری های منبع تنظیم شده برای حاوی کد و منابعی که می خواهید فقط با تنظیمات خاص بسته بندی شده استفاده کنید. به عنوان مثال ، اگر شما در حال ساخت نوع ساخت "DemodeBug" هستید ، که محصول متقاطع یک محصول "نسخه ی نمایشی" و نوع ساخت "اشکال زدایی" است ، Gradle به این دایرکتوری ها نگاه می کند و اولویت زیر را به آنها می دهد:

  1. src/demoDebug/ (ساخت مجموعه منبع مختلف)
  2. src/debug/ (مجموعه منبع نوع ساخت)
  3. src/demo/ (مجموعه منبع طعم محصول)
  4. src/main/ (مجموعه منبع اصلی)

مجموعه های منبع ایجاد شده برای ترکیب طعم دهنده های محصول باید شامل تمام ابعاد طعم دهنده باشند. به عنوان مثال ، مجموعه منبع Variant Build باید ترکیبی از نوع ساخت و تمام ابعاد طعم دهنده باشد. ادغام کد و منابع مربوط به پوشه هایی که چندین ابعاد عطر و طعم را پوشش نمی دهند ، پشتیبانی نمی شوند.

اگر چندین طعم محصول را با هم ترکیب کنید ، اولویت بین طعم های محصول با ابعاد عطر و طعم متعلق به آنها تعیین می شود. هنگام لیست ابعاد طعم دهنده با ویژگی android.flavorDimensions ، طعم دهنده های محصول که متعلق به اولین ابعاد طعم دهنده شما است ، اولویت بالاتری نسبت به موارد متعلق به بعد طعم دوم و غیره دارند. علاوه بر این ، مجموعه ای از منبعی که شما برای ترکیبی از طعم دهنده های محصول ایجاد می کنید ، از اولویت بالاتری نسبت به مجموعه های منبع که متعلق به یک عطر و طعم محصول جداگانه است ، دارند.

ترتیب اولویت تعیین می کند که مجموعه منبع اولویت بالاتری دارد که Gradle کد و منابع را ترکیب کند. از آنجا که دایرکتوری Set demoDebug/ Source به احتمال زیاد شامل پرونده هایی است که مخصوص آن نوع ساخت هستند ، اگر demoDebug/ شامل پرونده ای باشد که در debug/ ، Gradle از پرونده در مجموعه demoDebug/ Source استفاده می کند. به طور مشابه ، Gradle به پرونده های موجود در نوع ساخت می دهد و منبع عطر و طعم محصول اولویت بالاتری را نسبت به همان پرونده ها در main/ قرار می دهد. Gradle هنگام استفاده از قوانین ساخت زیر ، این دستور اولویت را در نظر می گیرد:

  • تمام کد منبع موجود در kotlin/ یا java/ Direcieties برای تولید یک خروجی واحد با هم گردآوری می شوند.

    توجه: برای یک نوع ساخت خاص ، Gradle در صورت مواجهه با دو یا چند دایرکتوری مجموعه منبع که کلاس Kotlin یا Java را تعریف کرده اند ، خطای ساخت را به وجود می آورد. به عنوان مثال ، هنگام ساختن یک برنامه اشکال زدایی ، شما نمی توانید src/debug/Utility.kt و src/main/Utility.kt ، زیرا Gradle به هر دو دایرکتوری در طول فرآیند ساخت نگاه می کند و خطای "کلاس تکراری" را پرتاب می کند . اگر می خواهید نسخه های مختلفی از Utility.kt برای انواع مختلف ساخت ، هر نوع ساخت باید نسخه خاص خود را از پرونده تعریف کند و آن را در مجموعه main/ منبع قرار ندهد.

  • مانیفست ها با هم در یک مانیفست ادغام می شوند. اولویت به همان ترتیب لیست در مثال قبلی آورده شده است. یعنی تنظیمات مانیفست برای یک نوع ساخت ، تنظیمات مانیفست را برای طعم محصول و غیره نادیده می گیرد. برای کسب اطلاعات بیشتر ، در مورد ادغام مانیفست بخوانید.
  • پرونده های موجود در values/ دایرکتوری ها با هم ادغام می شوند. اگر دو پرونده دارای یک نام یکسان باشند ، مانند دو پرونده strings.xml ، اولویت به همان ترتیب لیست در مثال قبلی آورده شده است. یعنی مقادیر تعریف شده در یک فایل در مجموعه منبع ساخت و ساز مقادیر تعریف شده در همان پرونده را در یک عطر و طعم محصول و غیره غلبه کنید.
  • منابع موجود در res/ و asset/ دایرکتوری ها با هم بسته بندی می شوند. اگر منابعی با همین نام در دو یا چند منبع منبع تعریف شده باشد ، اولویت به همان ترتیب لیست در مثال قبلی ارائه می شود.
  • Gradle منابع و مانیفست هایی را که با وابستگی ماژول کتابخانه در هنگام ساخت برنامه کمترین اولویت را ارائه می دهد ، می دهد.

وابستگی ها را اعلام کنید

برای پیکربندی وابستگی به یک نوع ساخت خاص یا مجموعه منبع آزمایش ، پیشوند نام نوع ساخت یا منبع آزمایش را که قبل از کلمه کلیدی Implementation تنظیم شده است ، همانطور که در مثال زیر نشان داده شده است ، پیشوند کنید:

کاتلین

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    "freeImplementation"(project(":mylibrary"))

    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}

شیار

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    freeImplementation project(":mylibrary")

    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

برای کسب اطلاعات بیشتر در مورد پیکربندی وابستگی ها ، به افزودن وابستگی های افزودنی مراجعه کنید.

از مدیریت وابستگی آگاهانه متفاوت استفاده کنید

افزونه Android Gradle 3.0.0 و بالاتر شامل یک مکانیسم وابستگی جدید است که به طور خودکار با انواع مختلف در هنگام مصرف یک کتابخانه مطابقت دارد. این بدان معنی است که نوع debug یک برنامه به طور خودکار از نوع debug کتابخانه و غیره استفاده می کند. همچنین در هنگام استفاده از طعم دهنده ها کار می کند: یک نوع برنامه freeDebug یک برنامه ، یک نوع freeDebug کتابخانه را مصرف می کند.

برای اینکه این افزونه به طور دقیق با انواع مختلف مطابقت داشته باشد ، باید برای مواردی که در آن یک مسابقه مستقیم امکان پذیر نیست ، تطبیق دهنده های تطبیق را ارائه دهید .

به عنوان مثال ، فرض کنید برنامه شما نوع ساخت و ساز به نام "مرحله بندی" را پیکربندی می کند ، اما یکی از وابستگی های کتابخانه ای آن نیست. هنگامی که این افزونه سعی می کند نسخه "مرحله بندی" برنامه خود را بسازد ، نمی داند از کدام نسخه از کتابخانه استفاده کند ، و یک پیام خطایی شبیه به موارد زیر مشاهده خواهید کرد:

Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
    project :app

خطاهای ساخت و سازم مربوط به تطبیق نوع را حل کنید

این افزونه شامل عناصر DSL برای کمک به شما در کنترل چگونگی حل و فصل GRADLE موقعیت هایی است که در آن یک نوع مستقیم بین یک برنامه و وابستگی امکان پذیر نیست.

در زیر لیستی از موضوعات مربوط به تطبیق وابستگی به آگاه و نحوه حل آنها با استفاده از خواص DSL وجود دارد:

  • برنامه شما شامل یک نوع ساخت و ساز است که وابستگی به کتابخانه ندارد.

    به عنوان مثال ، برنامه شما شامل نوع ساخت "مرحله بندی" است ، اما وابستگی فقط شامل انواع ساخت "اشکال زدایی" و "انتشار" است.

    توجه داشته باشید که هیچ مشکلی وجود ندارد که وابستگی کتابخانه شامل یک نوع ساخت باشد که برنامه شما انجام نمی دهد. دلیل این امر این است که این افزونه هرگز درخواست نمی کند که نوع از وابستگی باشد.

    همانطور که در اینجا نشان داده شده است ، برای مشخص کردن مسابقات جایگزین برای یک نوع ساخت خاص ، matchingFallbacks استفاده کنید:

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        buildTypes {
            getByName("debug") {}
            getByName("release") {}
            create("staging") {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks += listOf("debug", "qa", "release")
            }
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
  • برای یک بعد طعم دار که در برنامه و وابستگی کتابخانه آن وجود دارد ، برنامه شما شامل طعم دهنده هایی است که کتابخانه ندارد.

    به عنوان مثال ، هم برنامه شما و هم وابستگی های کتابخانه ای آن شامل ابعاد عطر و طعم "لایه" هستند. با این حال ، بعد "لایه" در برنامه شامل طعم های "رایگان" و "پرداخت شده" است ، اما یک وابستگی فقط شامل طعم های "نسخه ی نمایشی" و "پرداخت شده" برای همان بعد است.

    توجه داشته باشید که برای یک بعد طعم داده شده که هم در برنامه و هم در وابستگی به کتابخانه آن وجود دارد ، مشکلی وجود ندارد که یک کتابخانه شامل عطر و طعم محصول باشد که برنامه شما ندارد. دلیل این امر این است که این افزونه هرگز از این عطر و طعم از وابستگی درخواست نمی کند.

    برای مشخص کردن مسابقات جایگزین برای طعم محصول "رایگان" برنامه ، همانطور که در اینجا نشان داده شده است ، از matchingFallbacks استفاده کنید:

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions += "tier"
        productFlavors {
            create("paid") {
                dimension = "tier"
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            create("free") {
                dimension = "tier"
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks += listOf("demo", "trial")
            }
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
  • وابستگی کتابخانه شامل ابعاد طعم دهنده ای است که برنامه شما ندارد.

    به عنوان مثال ، وابستگی کتابخانه شامل طعم دهنده هایی برای بعد "minapi" است ، اما برنامه شما شامل طعم دهنده هایی برای بعد "لایه" است. هنگامی که می خواهید نسخه "FreedeBug" برنامه خود را بسازید ، این افزونه نمی داند که از نسخه "MinApi23Debug" یا "minapi18debug" از وابستگی استفاده کند.

    توجه داشته باشید که هیچ مشکلی وجود ندارد که برنامه شما شامل ابعاد عطر و طعم باشد که وابستگی کتابخانه ای انجام نمی دهد. دلیل این امر این است که این افزونه با طعم های تنها ابعادی که در وابستگی وجود دارد مطابقت دارد. به عنوان مثال ، اگر وابستگی ابعادی را برای ABIS شامل نشود ، نسخه "Freex86Debug" برنامه شما از نسخه "FreedeBug" وابستگی استفاده می کند.

    از missingDimensionStrategy در بلوک defaultConfig استفاده کنید تا طعم پیش فرض برای افزونه را از هر بعد گمشده انتخاب کنید ، همانطور که در نمونه زیر نشان داده شده است. همچنین می توانید انتخاب های خود را در بلوک productFlavors نادیده بگیرید ، بنابراین هر عطر و طعم می تواند یک استراتژی تطبیق متفاوت را برای ابعاد گمشده مشخص کند.

    کاتلین

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy("minApi", "minApi18", "minApi23")
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy("abi", "x86", "arm64")
        }
        flavorDimensions += "tier"
        productFlavors {
            create("free") {
                dimension = "tier"
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy("minApi", "minApi23", "minApi18")
            }
            create("paid") {}
        }
    }

    شیار

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the 'minApi' dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }

برای اطلاعات بیشتر ، به matchingFallbacks و missingDimensionStrategy در افزونه Android Gradle DSL مراجعه کنید.

تنظیمات امضا را پیکربندی کنید

Gradle APK یا AAB ساخت شما را امضا نمی کند ، مگر اینکه صریحاً پیکربندی امضای این ساخت را تعریف کنید. اگر هنوز کلید امضاء ندارید ، با استفاده از Android Studio یک کلید بارگذاری و کلید اصلی ایجاد کنید .

برای پیکربندی دستی تنظیمات امضا برای نوع ساخت نسخه خود با استفاده از تنظیمات ساخت Gradle:

  1. ایجاد یک کلیدی. کلیدی کلیدی یک فایل باینری است که شامل مجموعه ای از کلیدهای خصوصی است. شما باید کلید اصلی خود را در مکانی امن و ایمن نگه دارید.
  2. یک کلید خصوصی ایجاد کنید. از یک کلید خصوصی برای امضای برنامه شما برای توزیع استفاده می شود و هرگز با برنامه درج نمی شود یا به اشخاص ثالث غیرمجاز فاش نمی شود.
  3. پیکربندی امضای را به پرونده module- build.gradle.kts اضافه کنید:

    کاتلین

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

    شیار

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

توجه: از جمله رمزهای عبور برای کلید انتشار و کلید اصلی در داخل پرونده ساخت ، یک روش امنیتی خوب نیست. در عوض ، فایل ساخت را پیکربندی کنید تا این رمزهای عبور را از متغیرهای محیط به دست آورید یا فرآیند ساخت را برای این گذرواژه‌ها بخواهید.

برای به دست آوردن این رمزهای عبور از متغیرهای محیط:

کاتلین

storePassword = System.getenv("KSTOREPWD")
keyPassword = System.getenv("KEYPWD")

شیار

storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

از طرف دیگر ، می توانید کلید اصلی را از یک فایل Properties محلی بارگیری کنید. به دلایل امنیتی ، این پرونده را به کنترل منبع اضافه نکنید. در عوض ، آن را به صورت محلی برای هر توسعه دهنده تنظیم کنید. برای کسب اطلاعات بیشتر ، حذف اطلاعات امضاء از پرونده های ساخت خود را بخوانید.

پس از اتمام این فرآیند ، می توانید برنامه خود را توزیع کرده و آن را در Google Play منتشر کنید.

هشدار: کلید اصلی و کلید خصوصی خود را در مکانی امن و ایمن نگه دارید و اطمینان حاصل کنید که از آنها پشتیبان تهیه می کنید. اگر از امضای برنامه Play استفاده می کنید و کلید بارگذاری خود را از دست می دهید ، می توانید با استفاده از کنسول Play مجدداً تنظیم مجدد کنید . اگر در حال انتشار یک برنامه بدون امضای برنامه Play (برای برنامه های ایجاد شده قبل از اوت 2021) هستید و کلید امضای برنامه خود را از دست می دهید ، قادر نخواهید بود به روزرسانی در برنامه خود منتشر کنید ، زیرا همیشه باید تمام نسخه های برنامه خود را با آن امضا کنید همان کلید

امضای برنامه های سیستم عامل

هنگام انتشار برنامه های OS Wear ، هر دو APK Watch و APK اختیاری باید با همان کلید امضا شوند. برای کسب اطلاعات بیشتر در مورد بسته بندی و امضای برنامه های سیستم عامل Wear ، به بسته بندی و توزیع برنامه های Wear مراجعه کنید.