نسخه های جاوا در بیلدهای اندروید

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

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

واژه‌نامه

کیت توسعه جاوا (JDK)
کیت توسعه جاوا (JDK) شامل موارد زیر است:
  • ابزارهایی مانند کامپایلر، پروفایلر و سازنده آرشیو. این ابزارها در پشت صحنه و در حین ساخت برنامه برای ایجاد آن استفاده می‌شوند.
  • کتابخانه‌هایی حاوی APIهایی که می‌توانید از کد منبع کاتلین یا جاوای خود فراخوانی کنید. توجه داشته باشید که همه توابع در اندروید در دسترس نیستند.
  • ماشین مجازی جاوا (JVM)، یک مفسر که برنامه‌های جاوا را اجرا می‌کند. شما از JVM برای اجرای محیط توسعه یکپارچه اندروید استودیو و ابزار ساخت Gradle استفاده می‌کنید. JVM در دستگاه‌ها یا شبیه‌سازهای اندروید استفاده نمی‌شود.
زمان اجرای JetBrains (JBR)
JetBrains Runtime (JBR) یک JDK بهبود یافته است که با اندروید استودیو توزیع شده است. این JDK شامل چندین بهینه‌سازی برای استفاده در اندروید استودیو و محصولات مرتبط با JetBrains است، اما می‌تواند برای اجرای سایر برنامه‌های جاوا نیز مورد استفاده قرار گیرد.

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

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

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

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

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

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

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

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

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

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

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

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

شکل 2. تنظیمات Gradle JDK در اندروید استودیو

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

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

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

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

برای مثال، افزونه‌ی اندروید Gradle نسخه ۸.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`.

از کدام API های جاوا می‌توانم در کد منبع جاوا یا کاتلین خود استفاده کنم؟

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

کاتلین

android {
    ...
    compileSdk = 33
}

گرووی

android {
    ...
    compileSdk 33
}

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

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

اندروید جاوا API و ویژگی‌های زبانی پشتیبانی‌شده
۱۴ (API 34) ۱۷ کتابخانه‌های اصلی
۱۳ (API ۳۳) ۱۱ کتابخانه‌های اصلی
۱۲ (API 32) ۱۱ رابط برنامه‌نویسی جاوا
۱۱ و پایین‌تر نسخه‌های اندروید

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

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

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

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

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

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

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

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

کاتلین

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

گرووی

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

این روش در صورتی جواب می‌دهد که منبع شما کاتلین، جاوا یا ترکیبی از هر دو باشد.

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

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

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

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

کاتلین

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

گرووی

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

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

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

ویژگی‌های targetCompatibility و jvmTarget به ترتیب نسخه قالب کلاس جاوا را که هنگام تولید بایت‌کد برای منبع کامپایل‌شده جاوا و کاتلین استفاده می‌شود، تعیین می‌کنند.

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

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

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

کاتلین

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

گرووی

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}

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