שימוש בתכונות שפה ובממשקי API של Java 8

הפלאגין Android Gradle בגרסה 3.0.0 ואילך תומך בכל תכונות השפה של Java 7 ותת-קבוצה של תכונות שפת Java 8 שמשתנים בהתאם לגרסת הפלטפורמה. מתי במהלך יצירת האפליקציה באמצעות הפלאגין Android Gradle מגרסה 4.0.0 ואילך, ניתן להשתמש חלק מממשקי ה-API בשפה Java 8 ללא צורך ברמת API מינימלית אפליקציה.

בדף זה מתוארות תכונות השפה של Java 8 שניתן להשתמש בהן, להגדיר את הפרויקט לשימוש בהם, ואת כל הבעיות הידועות שאתם עשויים להיתקל בהן. צפו בסרטון הבא לקבלת סקירה כללית של תכונות השפה של Java 8.

הפלאגין Android Gradle מספק תמיכה מובנית לשימוש בסוגים מסוימים של Java 8 תכונות שפה וספריות של צד שלישי שמשתמשות בהן. שרשרת הכלים שמוגדרת כברירת מחדל משתמשת בתכונות השפה החדשות באמצעות טרנספורמציות בבייטקוד, שנקראות desugar, כחלק מאוסף D8/R8 של קובצי הכיתות בקוד DEX, כפי שמוצג באיור 1.

תמיכה בתכונות השפה Java 8 באמצעות בייטקוד 'desugar'
    טרנספורמציות
איור 1. תמיכה בתכונות של שפת Java 8 באמצעות desugar של טרנספורמציות בבייטקוד.

תמיכה בתכונות השפה Java 8 (פלאגין Android Gradle 3.0.0 ומעלה)

כדי להתחיל להשתמש בתכונות השפה הנתמכות של Java 8:

  1. עדכון הפלאגין של Android Gradle לגרסה 3.0.0 ומעלה.
  2. בכל מודול שמשתמש ב-Java 8 בשפה מסוימת (בקוד המקור או באמצעות יחסי תלות), מעדכנים את קובץ build.gradle או build.gradle.kts של המודול כמו שמוצג בהמשך:

Kotlin

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

מגניב

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

כשמפתחים את האפליקציה באמצעות הפלאגין Android Gradle מגרסה 3.0.0 ואילך, שהפלאגין לא תומך בכל התכונות של שפת Java 8. השפה הבאה התכונות זמינות בכל רמת API:

תכונה של שפת Java 8 הערות
ביטויי למבדה Android לא תומך בסריאליזציה של ביטויי lambda.
הפניות של שיטות  
סוג הערות מידע על הערות לגבי סוגים זמין רק בזמן הידור, לא בזמן הריצה. הפלטפורמה תומכת TYPE ברמת API 24 ומטה, אבל לא ב-ElementType.TYPE_USE, או ElementType.TYPE_PARAMETER
שיטות ברירת המחדל והממשק הסטטי  
הערות חוזרות  

בנוסף לתכונות השפה האלה של Java 8, הפלאגין של Android Gradle גרסה 3.0.0 ומעלה מרחיבה את התמיכה עבור try-with-resources לכל רמות ה-API של Android.

מוצרי סוכר לא תומכים MethodHandle.invoke או MethodHandle.invokeExact אם קוד המקור או אחד מיחסי התלות של המודולים משתמשים באחת מהשיטות האלה, יש לציין minSdkVersion 26 ומעלה. אחרת, מקבלים השגיאה הבאה:

Dex: Error converting bytecode to dex:
Cause: signature-polymorphic method called without --min-sdk-version >= 26

במקרים מסוימים, ייתכן שהמודול לא משתמש ב-invoke או ב-invokeExact גם אם הן נכללות בתלות של ספרייה. כדי להמשיך להשתמש הספרייה ההיא minSdkVersion 25 ומטה, הפעלת כיווץ קוד כדי להסיר שלא בשימוש. אם זה לא עובד, כדאי להשתמש בספרייה חלופית לא משתמש בשיטות שלא נתמכות.

תכונות השפה Java 8 ואילך ב-Android Gradle יישומי פלאגין 3.0.0 ומעלה ולא יוצרים סיווגים או ממשקי API נוספים. (למשל java.util.stream.*) זמין לשימוש בגרסאות ישנות יותר של Android. ב-Android Gradle, יש תמיכה בתהליך הסרה חלקי של Java API יישומי פלאגין בגרסה 4.0.0 ומעלה, כמו שמתואר בקטע הבא.

תמיכה בהסרת סוכר מממשק API של Java 8+ (Android Gradle Plugin 4.0.0 ואילך)

אם אתם מפתחים את האפליקציה באמצעות הפלאגין Android Gradle מגרסה 4.0.0 ואילך, מרחיב את התמיכה לשימוש במספר ממשקי API בשפת Java 8 ללא דרישה של רמת API מינימלית לאפליקציה. עם פלאגין Android Gradle בגרסה 7.4.0 או מספר ממשקי API בשפה Java 11 זמינים גם הם זמינים לספרייה 2.0.0 ומעלה.

התמיכה הנוספת הזו בגרסאות ישנות יותר של הפלטפורמה מתאפשרת כי הפלאגין גרסה 4.0.0 ואילך מרחיבה את מנוע הסרת הסוכר גם לשפת Java ללא סוכר ממשקי API. ניתן לכלול ממשקי API בשפה רגילה שהיו זמינים רק בשפות הבאות: גרסאות אחרונות של Android (כמו java.util.streams) באפליקציות שתומכות בגרסאות קודמות גרסאות Android.

קבוצות ממשקי ה-API הבאות נתמכות בפיתוח האפליקציה שלכם באמצעות Android פלאגין של Gradle מגרסה 4.0.0 ואילך:

  • שידורים ברצף (java.util.stream)
  • קבוצת משנה של java.time
  • java.util.function
  • תוספות אחרונות לjava.util.{Map,Collection,Comparator}
  • אופציונלי (java.util.Optional, java.util.OptionalInt ו- java.util.OptionalDouble) וכמה כיתות חדשות
  • כמה תוספות ל-java.util.concurrent.atomic (שיטות חדשות בנושא AtomicInteger, AtomicLong וגם AtomicReference)
  • ConcurrentHashMap (עם תיקוני באגים ב-Android 5.0)

עם פלאגין Android Gradle מגרסה 7.4.0 ואילך, ממשקי API נוספים של Java 11 למשל, קבוצת משנה של חבילת java.nio.file.

לרשימה המלאה של ממשקי ה-API הנתמכים: ממשקי API של Java 8 ואילך שזמינים לאחר הסרת סוכרים וגם ממשקי API של Java 11 ואילך זמינים דרך הסרת סוכרים.

כדי לתמוך בממשקי ה-API של השפות האלה, הפלאגין יוצר קובץ DEX נפרד יישום של ממשקי ה-API החסרים באפליקציה שלכם. תהליך ההסרה משכתב את קוד האפליקציה כך שישתמש בספרייה הזו במקום זאת ב בסביבת זמן ריצה.

כדי להפעיל תמיכה בממשקי ה-API של השפה האלה בכל גרסה של Android Platform:

  1. עדכון הפלאגין של Android Gradle לגרסה 4.0.0 (ומעלה).
  2. כוללים את הפרטים הבאים במודול האפליקציה קובץ build.gradle או build.gradle.kts:

Kotlin

android {
    defaultConfig {
        // Required when setting minSdkVersion to 20 or lower
        multiDexEnabled = true
    }

    compileOptions {
        // Flag to enable support for the new language APIs

        // For AGP 4.1+
        isCoreLibraryDesugaringEnabled = true
        // For AGP 4.0
        // coreLibraryDesugaringEnabled = true

        // Sets Java compatibility to Java 8
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    // For AGP 7.4+
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
    // For AGP 7.3
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3")
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.9")
}

מגניב

android {
    defaultConfig {
        // Required when setting minSdkVersion to 20 or lower
        multiDexEnabled true
    }

    compileOptions {
        // Flag to enable support for the new language APIs
        coreLibraryDesugaringEnabled true
        // Sets Java compatibility to Java 8
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // For AGP 7.4+
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
    // For AGP 7.3
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3'
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.9'
}

שימו לב: ייתכן שתצטרכו לכלול גם את קטע הקוד הקודם בספרייה build.gradle או build.gradle.kts של המודול אם:

  • הבדיקות האינסטרומנטטיביות של מודול הספרייה משתמשות בממשקי ה-API לשפה האלה ( באופן ישיר, או באמצעות מודול הספרייה או יחסי התלות שלו. ככה עושים את זה: ממשקי ה-API החסרים סופקו ל-APK של הבדיקה האינסטרומנטלית.

  • אתם רוצים להריץ איתור שגיאות בקוד במודול הספרייה בנפרד. המטרה היא לעזור איתור שגיאות בקוד (lint) מזהה שימושים חוקיים בממשקי ה-API של השפה ונמנע מדיווח False אזהרות.

כמו כן, חשוב לציין שאפשר לשלב את הסרת הסוכר מ-API עם כיווץ, אבל רק כשמשתמשים בכיווץ R8.

גרסאות

הטבלה הבאה מציגה את הגרסאות של ספריית Java 8+ API הגרסה המינימלית של הפלאגין Android Gradle שתומכת בכל גרסה:

גרסה הגרסה המינימלית של הפלאגין של Android Gradle
1.1.9 4.0.0
1.2.3 7.3.0
2.0.3 7.4.0-alpha10

לפרטים על הגרסאות של ספריית Java 8+ API, אפשר לעיין במאמר קובץ CHANGELOG.md במאגר desugar_jdk_libs של GitHub.