نسخه‌های جاوا در ساخت‌های Android

چه کد منبع شما به زبان Java،‏ Kotlin، یا هر دو نوشته شده باشد، چند جا وجود دارد که باید نسخه زبان Java یا JDK را برای ساخت انتخاب کنید.

نمای کلی روابط JDK در ساخت Gradle
شکل ۱. روابط JDK در ساخت

واژه‌نامه

Java Development Kit (JDK)
کیت توسعه Java (JDK) شامل موارد زیر است:
  • ابزارهایی مثل گردآورنده، نمایه‌ساز، و بایگانی‌ساز. این‌ها در پشت صحنه درطول ساخت شما برای ایجاد برنامه شما استفاده می‌شوند.
  • کتابخانه‌های حاوی میاناهای برنامه‌سازی کاربردی که می‌توانید از کد منبع Kotlin یا Java خود فراخوانی کنید. توجه داشته باشید که همه عملکردها در Android دردسترس نیستند.
  • «ماشین مجازی جاوا» (JVM)، مفسری که برنامه‌های جاوا را اجرا می‌کند. از JVM برای اجرای IDE «استودیو Android» و ابزار ساخت Gradle استفاده می‌کنید. از JVM در دستگاه‌های Android یا شبیه‌سازها استفاده نمی‌شود.
JetBrains Runtime (JBR)
زمان اجرای JetBrains (JBR) یک JDK بهبودیافته است که همراه با Android Studio توزیع می‌شود. این نسخه شامل چندین بهینه‌سازی برای استفاده در «استودیو» و محصولات مرتبط JetBrains است، اما می‌توان از آن برای اجرای برنامه‌های دیگر Java نیز استفاده کرد.

چگونه JDK را برای اجرای Android Studio انتخاب کنم؟

توصیه می‌کنیم از JBR برای اجرای Android Studio استفاده کنید. این نسخه با Android Studio مستقر می‌شود و برای آزمایش آن استفاده می‌شود و شامل بهبودهایی برای استفاده بهینه از Android Studio است. برای اطمینان از این موضوع، متغیر محیطی STUDIO_JDK را تنظیم نکنید.

متن‌های راه‌اندازی برای Android Studio به‌ترتیب زیر به‌دنبال JVM می‌گردند:

  1. ‫STUDIO_JDK متغیر محیط
  2. ‫studio.jdk دایرکتوری (در توزیع «استودیو Android»)
  3. دایرکتوری jbr (زمان اجرای JetBrains)، در توزیع Android Studio. توصیه می‌شود.
  4. ‫JDK_HOME متغیر محیط
  5. ‫JAVA_HOME متغیر محیط
  6. ‫java اجرایی در متغیر محیط PATH

چگونه انتخاب کنم کدام JDK ساخت‌های Gradle من را اجرا کند؟

اگر Gradle را بااستفاده از دکمه‌های «استودیو Android» اجرا کنید، از JDK تنظیم‌شده در تنظیمات «استودیو Android» برای اجرای Gradle استفاده می‌شود. اگر Gradle را در پایانه اجرا کنید، چه در داخل و چه در خارج Android Studio، متغیر محیطی JAVA_HOME (درصورت تنظیم) تعیین می‌کند که کدام JDK متن‌های Gradle را اجرا کند. اگر JAVA_HOME تنظیم نشده باشد، از فرمان java در متغیر محیط PATH استفاده می‌کند.

برای دریافت نتایج یکنواخت‌تر، مطمئن شوید که JAVA_HOME متغیر محیطی و پیکربندی Gradle JDK در «استودیو Android» را روی همان JDK تنظیم کرده‌اید.

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

اگر ساخت‌ها را با JDK یا نسخه‌های Gradle مختلف شروع کنید، کارگزاران اضافی ایجاد می‌شود که CPU و حافظه بیشتری مصرف می‌کنند.

پیکربندی Gradle JDK در «استودیو Android»

برای اصلاح پیکربندی Gradle JDK پروژه موجود، تنظیمات Gradle را از File (فایل) (یا Android Studio در macOS) > Settings (تنظیمات) > Build, Execution, Deployment (ساخت، اجرا، استقرار) > Build Tools (ابزارهای ساخت) > Gradle باز کنید. منو کرکره‌ای Gradle JDK شامل گزینه‌های زیر برای انتخاب است:

  • ماکروهایی مثل JAVA_HOME و GRADLE_LOCAL_JAVA_HOME
  • ورودی‌های جدول JDK در قالب vendor-version مثل jbr-17 که در فایل‌های پیکربندی Android ذخیره شده است
  • درحال بارگیری کیت توسعه جاوا
  • افزودن JDK خاص
  • ‫JDKهای شناسایی‌شده محلی از فهرست راهنمای نصب پیش‌فرض JDK سیستم‌عامل

گزینه انتخاب‌شده در گزینه gradleJvm در فایل .idea/gradle.xml پروژه ذخیره می‌شود و از وضوح مسیر JDK آن برای اجرای Gradle هنگام شروع ازطریق «استودیو Android» استفاده می‌شود.

شکل ۲. تنظیمات Gradle JDK در «استودیو Android».

کلان‌ها انتخاب پویای مسیر JDK پروژه را فعال می‌کنند:

  • ‫JAVA_HOME: از متغیر محیطی با همان نام استفاده می‌کند
  • GRADLE_LOCAL_JAVA_HOME: از دارایی java.home در فایل .gradle/config.properties استفاده می‌کند که به‌طور پیش‌فرض روی JetBrains Runtime تنظیم شده است.

از JDK انتخاب‌شده برای اجرای ساخت Gradle و حل کردن ارجاع‌های JDK API هنگام ویرایش کردن دستورگان ساخت و کد منبع استفاده می‌شود. توجه داشته باشید که compileSdk مشخص‌شده بیشتر نمادهای جاوا را که هنگام ویرایش و ساختن کد منبع دردسترس خواهند بود محدود می‌کند.

حتماً نسخه JDK را انتخاب کنید که بالاتر یا برابر با نسخه‌های JDK مورداستفاده افزایه‌هایی باشد که در ساخت Gradle استفاده می‌کنید. برای تعیین حداقل نسخه JDK موردنیاز برای «افزایه Android Gradle» (AGP)، به جدول سازگاری در یادداشت‌های انتشار مراجعه کنید.

برای مثال، نسخه ۸.x افزایه Android Gradle به JDK 17 نیاز دارد. اگر سعی کنید ساخت Gradle را که از آن استفاده می‌کند با نسخه قدیمی‌تری از ‏JDK اجرا کنید، پیامی مانند این گزارش می‌کند:

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
      Your current JDK is located in /usr/local/buildtools/java/jdk
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

از کدام Java API می‌توانم در کد منبع Java یا Kotlin استفاده کنم؟

برنامه Android می‌تواند از برخی‌از میاناهای برنامه‌سازی کاربردی تعریف‌شده در JDK استفاده کند، اما نه از همه آن‌ها. «کیت توسعه نرم‌افزار Android» پیاده‌سازی‌های بسیاری از توابع کتابخانه Java را به‌عنوان بخشی از میاناهای برنامه‌سازی کاربردی دردسترس خود تعریف می‌کند. دارایی compileSdk مشخص می‌کند هنگام کامپایل کردن کد منبع Kotlin یا Java از کدام نسخه «کیت توسعه نرم‌افزار Android» استفاده شود.

کاتلین

android {
    ...
    compileSdk = 36
}

شیک

android {
    ...
    compileSdk 36
}

هر نسخه Android از نسخه خاصی از JDK و زیرمجموعه‌ای از واسط‌های برنامه‌سازی کاربردی Java دردسترس آن پشتیبانی می‌کند. اگر از «میانای برنامه‌سازی کاربردی Java» استفاده می‌کنید که در compileSdk دردسترس است اما در minSdk مشخص‌شده دردسترس نیست، ممکن است بتوانید ازطریق فرایندی به‌نام desugaring در نسخه قبلی Android از این میانای برنامه‌سازی کاربردی استفاده کنید. برای دیدن میاناهای برنامه‌سازی کاربردی پشتیبانی‌شده، میاناهای برنامه‌سازی کاربردی Java 11+ دردسترس ازطریق desugaring را ببینید.

از این جدول برای تعیین اینکه هر «میانای برنامه‌سازی کاربردی» Android از کدام نسخه Java پشتیبانی می‌کند و جزئیات مربوط به اینکه کدام «میاناهای برنامه‌سازی کاربردی» Java دردسترس است کجا پیدا می‌شود استفاده کنید.

Android جاوا ویژگی‌های زبان و میانای برنامه‌سازی کاربردی پشتیبانی‌شده
‫۱۴ (API 34) 17 کتابخانه‌های اصلی
‫13 (API 33) 11 کتابخانه‌های اصلی
‫12 (API 32) 11 Java API
‫۱۱ و کمتر نسخه‌های Android

کدام JDK کد منبع Java را کامپایل می‌کند؟

‫زنجیره ابزار Java در JDK شامل گردآورنده Java است که برای گردآوری هرگونه کد منبع Java استفاده می‌شود. این JDK همچنین javadoc و آزمایش‌های واحد را درطول ساخت اجرا می‌کند.

زنجیره ابزار به‌طور پیش‌فرض از JDK استفاده‌شده برای اجرای Gradle استفاده می‌کند. اگر از پیش‌فرض استفاده کنید و ساخت را در ماشین‌های مختلف اجرا کنید (برای مثال، ماشین محلی شما و سرور «ادغام پیوسته» جداگانه)، نتایج ساخت شما درصورت استفاده از نسخه‌های مختلف JDK می‌تواند متفاوت باشد.

برای ایجاد ساختاری سازگارتر، می‌توانید نسخه زنجیره ابزار Java را به‌طور صریح مشخص کنید. مشخص کردن این:

  • ‫JDK سازگاری را در سیستم درحال اجرای ساخت پیدا می‌کند.
    • اگر هیچ JDK سازگاری وجود نداشته باشد (و یک حل‌کننده زنجیره ابزار تعریف شده باشد)، یکی را بارگیری می‌کند.
  • میاناهای برنامه‌سازی کاربردی Java زنجیره ابزار را برای فراخوانی از کد منبع نمایان می‌کند.
  • بااستفاده از نسخه زبان Java خود، منبع Java را گردآوری می‌کند.
  • پیش‌فرض‌های sourceCompatibility و targetCompatibility را ارائه می‌دهد.

توصیه می‌کنیم همیشه زنجیره ابزار Java را مشخص کنید و یا مطمئن شوید که JDK مشخص‌شده نصب شده است یا یک حل‌کننده زنجیره ابزار به ساخت خود اضافه کنید.

می‌توانید زنجیره ابزار را مشخص کنید که کد منبع شما به زبان Java، Kotlin، یا هر دو نوشته شده است. زنجیره ابزار را در سطح بالای فایل build.gradle(.kts) واحدتان مشخص کنید.

نسخه زنجیره ابزار Java را به‌این‌صورت مشخص کنید:

کاتلین

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

شیک

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

اگر منبع شما Kotlin،‏ Java، یا ترکیبی از هر دو باشد، این کار جواب می‌دهد.

نسخه JDK زنجیره ابزار می‌تواند با JDK مورداستفاده برای اجرای Gradle یکسان باشد، اما به‌خاطر داشته باشید که اهداف متفاوتی دارند.

از کدام ویژگی‌های منبع زبان جاوا می‌توانم در کد منبع جاوا استفاده کنم؟

دارایی sourceCompatibility تعیین می‌کند که کدام ویژگی‌های زبان Java درطول ترجمه منبع Java دردسترس باشد. بر منبع Kotlin تأثیر نمی‌گذارد.

sourceCompatibility را در فایل build.gradle(.kts) واحدتان به‌صورت زیر مشخص کنید:

کاتلین

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

شیک

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

اگر مشخص نشده باشد، این دارایی به‌طور پیش‌فرض از نسخه زنجیره ابزار Java استفاده می‌کند. اگر از زنجیره ابزار Java استفاده نمی‌کنید، به‌طور پیش‌فرض به نسخه‌ای که افزایه Android Gradle انتخاب کرده است (برای نمونه، Java 8 یا بالاتر) برمی‌گردد.

وقتی منبع Kotlin یا Java خود را کامپایل می‌کنم، از کدام ویژگی‌های باینری Java می‌توانم استفاده کنم؟

دارایی targetCompatibility نسخه قالب کلاس Java را که هنگام تولید کدبایت برای منبع Java و Kotlin کامپایل‌شده استفاده می‌شود تعیین می‌کند.

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

نسخه‌های مختلف Android از نسخه‌های مختلف Java پشتیبانی می‌کنند. با افزایش targetCompatibility می‌توانید از ویژگی‌های اضافی جاوا بهره ببرید، اما این کار ممکن است شما را مجبور کند حداقل نسخه کیت توسعه نرم‌افزار Android را نیز افزایش دهید تا مطمئن شوید ویژگی دردسترس است.

توجه داشته باشید که targetCompatibility باید بزرگ‌تر یا مساوی با sourceCompatibility باشد. در عمل، sourceCompatibility و targetCompatibility باید به‌طورکلی از مقدار یکسانی استفاده کنند. می‌توانید آن‌ها را به‌صورت زیر تنظیم کنید:

کاتلین

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

شیک

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

اگر از نسخه Kotlin پایین‌تر از ۲.۲ استفاده می‌کنید، باید kotlinOptions را نیز تنظیم کنید:

کاتلین

android {
    kotlinOptions {
        jvmTarget = "17"
    }
}

شیک

android {
    kotlinOptions {
        jvmTarget = "17"
    }
}

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