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

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

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

واژه‌نامه

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

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

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

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

  1. متغیر محیطی STUDIO_JDK
  2. دایرکتوری studio.jdk (در توزیع «استودیو Android»)
  3. jbr (JetBrains Runtime)، در توزیع 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 فرایندی به‌نام daemon ایجاد می‌کند تا ساخت واقعی را انجام دهد. تا زمانی‌که ساخت‌ها از همان نسخه JDK و Gradle استفاده می‌کنند، می‌توان از این فرایند مجدداً استفاده کرد. استفاده مجدد از daemon زمان لازم برای شروع JVM جدید و مقداردهی اولیه سیستم ساخت را کاهش می‌دهد.

اگر ساخت‌ها را با نسخه‌های مختلف 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 ذخیره شده‌اند
  • درحال بارگیری کیت توسعه جاوا
  • افزودن کیت توسعه جاوا خاص
  • کیت‌های توسعه جاوا که به‌طور محلی از فهرست راهنمای نصب پیش‌فرض کیت توسعه جاوا در سیستم‌عامل شناسایی شده‌اند

گزینه انتخاب‌شده در گزینه 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 هنگام ویرایش کردن کد منبع و دستورگان ساخت استفاده می‌شود. توجه داشته باشید که compileSdk مشخص‌شده محدودیت‌های بیشتری را بر نمادهای Java که هنگام ویرایش و ساخت کد منبع دردسترس خواهند بود اعمال می‌کند.

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

برای مثال، «افزایه Android Gradle» نسخه 8.x به 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 می‌تواند از برخی‌از میاناهای برنامه‌سازی کاربردی تعریف‌شده در «کیت توسعه جاوا» استفاده کند، اما نه همه آن‌ها. کیت توسعه نرم‌افزار Android پیاده‌سازی‌های بسیاری از توابع کتابخانه Java را به‌عنوان بخشی از میاناهای برنامه‌سازی کاربردی دردسترس خود تعریف می‌کند. ویژگی compileSdk مشخص می‌کند که هنگام کامپایل کردن کد منبع Kotlin یا Java، از کدام نسخه کیت توسعه نرم‌افزار Android استفاده شود.

کاتلین

android {
    ...
    compileSdk = 36
}

شیک

android {
    ...
    compileSdk 36
}

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

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

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

کدام «کیت توسعه جاوا» کد منبع Java من را کامپایل می‌کند؟

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

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

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

  • یک JDK سازگار را در سیستم درحال اجرای ساخت پیدا می‌کند.
    • اگر کیت توسعه جاوا سازگاری وجود نداشته باشد (و حل‌کننده زنجیره ابزار تعریف شده باشد)، یکی را بارگیری می‌کند.
  • میاناهای برنامه‌سازی کاربردی 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 ایجاد می‌کردند. برخی‌از این ویژگی‌ها بعداً به جاوا اضافه شد. با سطوح targetCompatibility بالاتر، کامپایلر Kotlin ممکن است مستقیماً از ویژگی Java استفاده کند که ممکن است منجر به عملکرد بهتر شود.

نسخه‌های مختلف Android از نسخه‌های مختلف Java پشتیبانی می‌کنند. با افزایش دادن targetCompatibility می‌توانید از ویژگی‌های اضافی Java بهره ببرید، اما این کار ممکن است شما را مجبور کند حداقل نسخه کیت توسعه نرم‌افزار 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 استفاده نمی‌کنید، ممکن است مقادیر پیش‌فرض متفاوت باشد و باعث ایجاد مشکل در ساخت شود. بنابراین، توصیه می‌کنیم که همیشه این مقادیر را به‌طور صریح مشخص کنید یا از زنجیره ابزار Java استفاده کنید.