افزودن وابستگی های ساخت

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

افزودن یک کتابخانه یا وابستگی افزونه

بهترین راه برای افزودن و مدیریت وابستگی‌های ساخت، استفاده از کاتالوگ‌های نسخه است، روشی که پروژه‌های جدید به طور پیش‌فرض از آن استفاده می‌کنند. این بخش رایج‌ترین انواع پیکربندی‌های مورد استفاده برای پروژه‌های اندروید را پوشش می‌دهد؛ برای گزینه‌های بیشتر به مستندات Gradle مراجعه کنید. برای مثالی از برنامه‌ای که از کاتالوگ‌های نسخه استفاده می‌کند، به «اکنون در اندروید» مراجعه کنید. اگر از قبل وابستگی‌های ساخت را بدون کاتالوگ‌های نسخه تنظیم کرده‌اید و یک پروژه چند ماژوله دارید، مهاجرت را توصیه می‌کنیم.

برای راهنمایی در مورد افزودن و مدیریت وابستگی‌های بومی (که رایج نیست)، به وابستگی‌های بومی مراجعه کنید.

در مثال زیر، یک وابستگی باینری از راه دور ( کتابخانه Jetpack Macrobenchmarkیک وابستگی ماژول کتابخانه محلی ( myLibrary ) و یک وابستگی افزونه (افزونه Android Gradle) را به پروژه خود اضافه می‌کنیم. در اینجا مراحل کلی برای افزودن این وابستگی‌ها به پروژه شما آمده است:

  1. یک نام مستعار برای نسخه وابستگی مورد نظر خود در بخش [versions] از فایل کاتالوگ نسخه، به نام libs.versions.toml (در زیر پوشه gradle در نمای Project یا Gradle Scripts در نمای Android ) اضافه کنید:

    [versions]
    agp = "8.3.0"
    androidx-macro-benchmark = "1.2.2"
    my-library = "1.4"
    
    [libraries]
    ...
    
    [plugins]
    ...
    

    نام‌های مستعار می‌توانند شامل خط تیره یا زیرخط باشند. این نام‌های مستعار مقادیر تو در تو ایجاد می‌کنند که می‌توانید در اسکریپت‌های ساخت به آنها ارجاع دهید. ارجاعات با نام کاتالوگ، بخش libs از libs.versions.toml ، شروع می‌شوند. هنگام استفاده از یک کاتالوگ تک نسخه‌ای، توصیه می‌کنیم مقدار پیش‌فرض "libs" را حفظ کنید.

  2. یک نام مستعار برای وابستگی در بخش‌های [libraries] (برای فایل‌های باینری از راه دور یا ماژول‌های کتابخانه محلی) یا [plugins] (برای افزونه‌ها) از فایل libs.versions.toml اضافه کنید.

    [versions]
    ...
    
    [libraries]
    androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" }
    my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" }
    
    [plugins]
    androidApplication = { id = "com.android.application", version.ref = "agp" }
    

    برخی از کتابخانه‌ها در یک فهرست مواد (BOM) منتشر شده موجود هستند که خانواده‌های کتابخانه‌ها و نسخه‌های آنها را گروه‌بندی می‌کند. می‌توانید یک BOM را در کاتالوگ نسخه و فایل‌های ساخت خود قرار دهید و اجازه دهید آن نسخه‌ها را برای شما مدیریت کند. برای جزئیات بیشتر به استفاده از فهرست مواد مراجعه کنید.

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

    کاتلین

    plugins {
      alias(libs.plugins.androidApplication)
    }
    
    dependencies {
      implementation(libs.androidx.benchmark.macro)
      implementation(libs.my.library)
    }

    گرووی

    plugins {
      alias 'libs.plugins.androidApplication'
    }
    
    dependencies {
      implementation libs.androidx.benchmark.macro
      implementation libs.my.library
    }

    ارجاعات افزونه شامل plugins پس از نام کاتالوگ و ارجاعات نسخه شامل versions پس از نام کاتالوگ می‌شوند (ارجاعات نسخه رایج نیستند؛ برای نمونه‌هایی از ارجاعات نسخه به وابستگی‌ها با شماره نسخه‌های یکسان مراجعه کنید.) ارجاعات کتابخانه شامل توصیف‌کننده libraries نمی‌شوند، بنابراین نمی‌توانید versions یا plugins در ابتدای نام مستعار کتابخانه استفاده کنید.

پیکربندی وابستگی‌ها

درون بلوک dependencies ، می‌توانید یک وابستگی کتابخانه‌ای را با استفاده از یکی از چندین پیکربندی وابستگی مختلف (مانند implementation نشان داده شده در قبل) اعلام کنید. هر پیکربندی وابستگی، دستورالعمل‌های مختلفی در مورد نحوه استفاده از وابستگی به Gradle ارائه می‌دهد. جدول زیر هر یک از پیکربندی‌هایی را که می‌توانید برای یک وابستگی در پروژه اندروید خود استفاده کنید، شرح می‌دهد.

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

استفاده از این پیکربندی وابستگی به جای api می‌تواند منجر به بهبود قابل توجه زمان ساخت شود، زیرا تعداد ماژول‌هایی را که سیستم ساخت باید دوباره کامپایل کند، کاهش می‌دهد. به عنوان مثال، اگر یک وابستگی implementation API خود را تغییر دهد، Gradle فقط آن وابستگی و ماژول‌هایی را که مستقیماً به آن وابسته هستند، دوباره کامپایل می‌کند. اکثر ماژول‌های برنامه و تست باید از این پیکربندی استفاده کنند.

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

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

compileOnly Gradle وابستگی را فقط به مسیر کلاس کامپایل اضافه می‌کند (یعنی به خروجی ساخت اضافه نمی‌شود). این زمانی مفید است که شما در حال ایجاد یک ماژول اندروید هستید و در طول کامپایل به وابستگی نیاز دارید، اما وجود آن در زمان اجرا اختیاری است. به عنوان مثال، اگر به کتابخانه‌ای وابسته هستید که فقط شامل حاشیه‌نویسی‌های زمان کامپایل است - که معمولاً برای تولید کد استفاده می‌شود اما اغلب در خروجی ساخت گنجانده نمی‌شود - می‌توانید آن کتابخانه را compileOnly علامت‌گذاری کنید.

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

نکته: شما نمی‌توانید از پیکربندی compileOnly با وابستگی‌های Android Archive (AAR) استفاده کنید.

runtimeOnly Gradle این وابستگی را فقط به خروجی ساخت، برای استفاده در زمان اجرا، اضافه می‌کند. یعنی، به مسیر کلاس کامپایل اضافه نمی‌شود. این مورد به ندرت در اندروید استفاده می‌شود، اما معمولاً در برنامه‌های سرور برای ارائه پیاده‌سازی‌های گزارش‌گیری استفاده می‌شود. به عنوان مثال، یک کتابخانه می‌تواند از یک API گزارش‌گیری استفاده کند که شامل پیاده‌سازی نیست. مصرف‌کنندگان آن کتابخانه می‌توانند آن را به عنوان یک وابستگی implementation اضافه کنند و یک وابستگی runtimeOnly را برای استفاده از پیاده‌سازی واقعی گزارش‌گیری لحاظ کنند.
ksp
kapt
annotationProcessor

این پیکربندی‌ها کتابخانه‌هایی را فراهم می‌کنند که حاشیه‌نویسی‌ها و سایر نمادهای موجود در کد شما را قبل از کامپایل پردازش می‌کنند. آن‌ها معمولاً کد شما را اعتبارسنجی می‌کنند یا کد اضافی تولید می‌کنند و کدی را که باید بنویسید کاهش می‌دهند.

برای افزودن چنین وابستگی، باید آن را با استفاده از پیکربندی‌های ksp ، kapt یا annotationProcessor به مسیر کلاس پردازنده حاشیه‌نویسی (annotation processor classpath) اضافه کنید. استفاده از این پیکربندی‌ها با جدا کردن مسیر کلاس کامپایل از مسیر کلاس پردازنده حاشیه‌نویسی، عملکرد ساخت را بهبود می‌بخشد. اگر Gradle پردازنده‌های حاشیه‌نویسی را در مسیر کلاس کامپایل پیدا کند، Compile Avoidance را غیرفعال می‌کند که تأثیر منفی بر زمان ساخت می‌گذارد (Gradle 5.0 و بالاتر پردازنده‌های حاشیه‌نویسی موجود در مسیر کلاس کامپایل را نادیده می‌گیرند).

افزونه‌ی اندروید Gradle فرض می‌کند که یک وابستگی، اگر فایل JAR آن شامل فایل زیر باشد، یک پردازنده‌ی حاشیه‌نویسی است:

META-INF/services/javax.annotation.processing.Processor

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

ksp یک پردازشگر نماد کاتلین است و توسط کامپایلر کاتلین اجرا می‌شود.

kapt و apt ابزارهای جداگانه‌ای هستند که حاشیه‌نویسی‌ها را قبل از اجرای کامپایلرهای کاتلین یا جاوا پردازش می‌کنند.

هنگام تصمیم‌گیری در مورد اینکه از کدام پیکربندی استفاده کنید، موارد زیر را در نظر بگیرید:

  • اگر پردازنده‌ای به عنوان پردازنده نماد کاتلین در دسترس است، از آن به عنوان یک وابستگی ksp استفاده کنید. برای جزئیات بیشتر در مورد استفاده از پردازنده‌های نماد کاتلین، به Migrate from kapt to ksp مراجعه کنید.
  • اگر پردازنده به عنوان پردازنده نماد کاتلین در دسترس نباشد:
    • اگر پروژه شما شامل سورس کاتلین است (اما می‌تواند شامل سورس جاوا نیز باشد)، از kapt برای گنجاندن آن استفاده کنید .
    • اگر پروژه شما فقط از منبع جاوا استفاده می‌کند، از annotationProcessor برای گنجاندن آن استفاده کنید.

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

lintChecks

از این پیکربندی برای اضافه کردن کتابخانه‌ای حاوی بررسی‌های lint که می‌خواهید Gradle هنگام ساخت پروژه برنامه اندروید شما اجرا کند، استفاده کنید.

توجه داشته باشید که AARهایی که حاوی فایل lint.jar هستند، به طور خودکار بررسی‌های تعریف شده در آن فایل lint.jar را اجرا می‌کنند؛ نیازی به اضافه کردن وابستگی صریح lintChecks نیست. این به شما امکان می‌دهد کتابخانه‌ها و بررسی‌های lint مرتبط را در یک وابستگی واحد تعریف کنید و اطمینان حاصل کنید که بررسی‌های شما هنگام استفاده مصرف‌کنندگان از کتابخانه شما اجرا می‌شوند.

lintPublish از این پیکربندی در پروژه‌های کتابخانه اندروید برای گنجاندن بررسی‌های lint که می‌خواهید Gradle آنها را در یک فایل lint.jar کامپایل کند و در AAR شما بسته‌بندی کند، استفاده کنید. این باعث می‌شود پروژه‌هایی که از AAR شما استفاده می‌کنند، آن بررسی‌های lint را نیز اعمال کنند. اگر قبلاً از پیکربندی وابستگی lintChecks برای گنجاندن بررسی‌های lint در AAR منتشر شده استفاده می‌کردید، باید آن وابستگی‌ها را به جای استفاده از پیکربندی lintPublish منتقل کنید.

کاتلین

dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}

گرووی

dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

پیکربندی وابستگی‌ها برای یک نوع ساخت خاص

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

برای مثال، برای اضافه کردن یک وابستگی باینری از راه دور فقط به محصول "رایگان" خود با استفاده از پیکربندی implementation ، از این استفاده کنید:

کاتلین

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:21.5.1")
}

گرووی

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
}

با این حال، اگر می‌خواهید برای گونه‌ای که ترکیبی از product flavor و build type است، وابستگی اضافه کنید، باید نام پیکربندی را مقداردهی اولیه کنید:

کاتلین

// Initializes a placeholder for the freeDebugImplementation dependency configuration.
val freeDebugImplementation by configurations.creating

dependencies {
    freeDebugImplementation(project(":free-support"))
}

گرووی

configurations {
    // Initializes a placeholder for the freeDebugImplementation dependency configuration.
    freeDebugImplementation {}
}

dependencies {
    freeDebugImplementation project(":free-support")
}

برای افزودن وابستگی‌های implementation برای تست‌های محلی و تست‌های instrumented، به این صورت عمل کنید:

کاتلین

dependencies {
    // 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("androidx.test.espresso:espresso-core:3.6.1")
}

گرووی

dependencies {
    // 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 'androidx.test.espresso:espresso-core:3.6.1'
}

با این حال، برخی پیکربندی‌ها در این شرایط منطقی نیستند. برای مثال، از آنجا که سایر ماژول‌ها نمی‌توانند به androidTest وابسته باشند، در صورت استفاده از پیکربندی androidTestApi با هشدار زیر مواجه می‌شوید:

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

ترتیب وابستگی

ترتیبی که وابستگی‌های خود را فهرست می‌کنید، اولویت هر کدام را نشان می‌دهد: کتابخانه اول از کتابخانه دوم اولویت بالاتری دارد، کتابخانه دوم از کتابخانه سوم اولویت بالاتری دارد و به همین ترتیب. این ترتیب در صورتی که منابع ادغام شوند یا عناصر مانیفست از کتابخانه‌ها در برنامه شما ادغام شوند، مهم است.

برای مثال، اگر پروژه شما موارد زیر را اعلام کند:

  • وابستگی به LIB_A و LIB_B (به همین ترتیب)
  • و LIB_A به LIB_C و LIB_D (به همین ترتیب) بستگی دارد
  • و LIB_B نیز به LIB_C بستگی دارد

سپس، ترتیب وابستگی مسطح به شرح زیر خواهد بود:

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

این تضمین می‌کند که هم LIB_A و هم LIB_B می‌توانند LIB_C لغو کنند؛ و LIB_D همچنان اولویت بالاتری نسبت به LIB_B دارد زیرا LIB_A (که به آن وابسته است) اولویت بالاتری نسبت به LIB_B دارد.

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

اطلاعات وابستگی برای کنسول Play

هنگام ساخت برنامه، AGP شامل فراداده‌هایی است که وابستگی‌های کتابخانه‌ای را که در برنامه شما کامپایل می‌شوند، توصیف می‌کند. هنگام آپلود برنامه، کنسول Play این فراداده‌ها را بررسی می‌کند تا هشدارهایی را برای مشکلات شناخته شده با SDKها و وابستگی‌هایی که برنامه شما استفاده می‌کند، ارائه دهد و در برخی موارد، بازخوردهای عملی را برای حل آن مشکلات ارائه دهد.

داده‌ها فشرده می‌شوند، توسط یک کلید امضای Google Play رمزگذاری می‌شوند و در بلوک امضای برنامه انتشار شما ذخیره می‌شوند. توصیه می‌کنیم این فایل وابستگی‌ها را برای یک تجربه کاربری ایمن و مثبت نگه دارید. می‌توانید با وارد کردن بلوک dependenciesInfo زیر در فایل build.gradle.kts ماژول خود، از این کار خودداری کنید.

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

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

بینش‌های SDK

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

  • SDKها توسط نویسندگانشان به عنوان منسوخ‌شده علامت‌گذاری شده‌اند.
  • SDKها سیاست‌های Play را نقض می‌کنند.
  • SDK ها دارای آسیب پذیری های امنیتی شناخته شده ای هستند.
  • SDK ها توسط نویسندگانشان منسوخ شده اند.

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

اضافه کردن وابستگی‌های ساخت بدون کاتالوگ نسخه

ما استفاده از کاتالوگ‌های نسخه را برای افزودن و مدیریت وابستگی‌ها توصیه می‌کنیم، اما پروژه‌های ساده ممکن است به آنها نیازی نداشته باشند. در اینجا مثالی از یک فایل ساخت که از کاتالوگ‌های نسخه استفاده نمی‌کند، آورده شده است:

کاتلین

plugins {
    id("com.android.application")
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
    // Dependency on a local library module
    implementation(project(":mylibrary"))
}

گرووی

plugins {
    id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
    // Dependency on a local library module
    implementation project(':mylibrary')
}

این فایل ساخت، یک وابستگی به نسخه ۱۲.۳ کتابخانه "app-magic" را در داخل گروه فضای نام "com.example.android" اعلام می‌کند. اعلان وابستگی باینری از راه دور، خلاصه‌ای از عبارت زیر است:

کاتلین

implementation(group = "com.example.android", name = "app-magic", version = "12.3")

گرووی

implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

فایل ساخت همچنین یک وابستگی به یک ماژول کتابخانه اندروید با نام "mylibrary" اعلام می‌کند؛ این نام باید با نام کتابخانه تعریف شده با include: در فایل settings.gradle.kts شما مطابقت داشته باشد. هنگامی که برنامه خود را می‌سازید، سیستم ساخت، ماژول کتابخانه را کامپایل کرده و محتوای کامپایل شده حاصل را در برنامه بسته‌بندی می‌کند.

فایل ساخت همچنین یک وابستگی به افزونه Android Gradle ( com.application.android ) اعلام می‌کند. اگر چندین ماژول دارید که از یک افزونه استفاده می‌کنند، فقط می‌توانید یک نسخه از افزونه را در مسیر ساخت در تمام ماژول‌ها داشته باشید. به جای مشخص کردن نسخه در هر یک از اسکریپت‌های ساخت ماژول، باید وابستگی افزونه را در اسکریپت ساخت ریشه به همراه نسخه وارد کنید و مشخص کنید که آن را اعمال نکنید. اضافه کردن apply false به Gradle می‌گوید که نسخه افزونه را یادداشت کند اما از آن در ساخت ریشه استفاده نکند. معمولاً اسکریپت ساخت ریشه به جز این بلوک plugins خالی است.

کاتلین

plugins {
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}

گرووی

plugins {
    id com.android.application version 8.3.0-rc02 apply false
}

اگر یک پروژه تک ماژولی دارید، می‌توانید نسخه را به صراحت در اسکریپت ساخت سطح ماژول مشخص کنید و اسکریپت ساخت سطح پروژه را خالی بگذارید:

کاتلین

plugins {
    id("com.android.application") version "8.3.0"
}

گرووی

plugins {
    id 'com.android.application' version '8.3.0-rc02'
}