ใช้ฟีเจอร์และ 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 และไลบรารีของบุคคลที่สามที่ใช้ฟีเจอร์เหล่านั้น โดย Toolchain เริ่มต้นจะใช้ฟีเจอร์ภาษาใหม่โดยทำการเปลี่ยนรูปแบบไบต์โค้ดที่เรียกว่า 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 (ในซอร์สโค้ดหรือผ่านทรัพยากร Dependency) ให้อัปเดตไฟล์ 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 หมายเหตุ
นิพจน์ Lambda Android ไม่รองรับการเรียงลำดับนิพจน์ Lambda
ข้อมูลอ้างอิงเกี่ยวกับวิธีการ  
คำอธิบายประกอบประเภท ข้อมูลคำอธิบายประกอบประเภทจะใช้ได้เฉพาะในเวลาคอมไพล์เท่านั้น ไม่ใช่ในรันไทม์ แพลตฟอร์มรองรับ TYPE ในระดับ API 24 ลงไป แต่ไม่รองรับ ElementType.TYPE_USE หรือ ElementType.TYPE_PARAMETER
วิธีการอินเทอร์เฟซเริ่มต้นและแบบคงที่  
คำอธิบายประกอบที่เกิดซ้ำ  

นอกจากฟีเจอร์ภาษา Java 8 เหล่านี้แล้ว ปลั๊กอิน Android Gradle เวอร์ชัน 3.0.0 ขึ้นไปยังขยายการรองรับ try-with-resources ไปยังระดับ API ของ Android ทุกระดับด้วย

Desugar ไม่รองรับ MethodHandle.invoke หรือ MethodHandle.invokeExact หากซอร์สโค้ดหรือทรัพยากร Dependency ของโมดูลรายการใดรายการหนึ่งใช้วิธีใดวิธีหนึ่งเหล่านี้ คุณต้องระบุ minSdkVersion 26 ขึ้นไป ไม่เช่นนั้น คุณจะได้รับข้อผิดพลาดต่อไปนี้

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

ในบางกรณี โมดูลอาจไม่ได้ใช้เมธอด invoke หรือ invokeExact แม้ว่าจะรวมอยู่ในทรัพยากร Dependency ของไลบรารีก็ตาม หากต้องการใช้ไลบรารีนั้นกับ minSdkVersion 25 หรือต่ำกว่าต่อไป ให้เปิดใช้การลดขนาดโค้ดเพื่อนำเมธอดที่ไม่ได้ใช้ออก หากไม่ได้ผล ให้พิจารณาใช้ไลบรารีอื่นที่ไม่ได้ใช้วิธีการที่ไม่รองรับ

ฟีเจอร์ภาษา Java 8 ขึ้นไปจะใช้กระบวนการ Desugaring ในปลั๊กอิน Android Gradle 3.0.0 ขึ้นไป และไม่ทำให้คลาสและ API เพิ่มเติม (เช่น java.util.stream.*) พร้อมใช้งานใน Android รุ่นเก่า การรองรับกระบวนการ Desugaring ของ Java API บางส่วนพร้อมใช้งานจากปลั๊กอิน Android Gradle 4.0.0 ขึ้นไป ตามที่อธิบายไว้ในส่วนต่อไปนี้

การรองรับกระบวนการ Desugaring ของ Java 8+ API (ปลั๊กอิน Android Gradle 4.0.0 ขึ้นไป)

หากคุณสร้างแอปโดยใช้ปลั๊กอิน Android Gradle 4.0.0 ขึ้นไป ปลั๊กอินจะขยายการรองรับการใช้ API ภาษา Java 8 จำนวนมากโดยไม่ต้องมีระดับ API ขั้นต่ำสำหรับแอปของคุณ เมื่อใช้ปลั๊กอิน Android Gradle 7.4.0 ขึ้นไป API ภาษา Java 11 จำนวนมากจะพร้อมใช้งานกับไลบรารี Desugared 2.0.0 ขึ้นไป

การรองรับเพิ่มเติมสำหรับแพลตฟอร์มเวอร์ชันเก่านี้เป็นไปได้เนื่องจากปลั๊กอิน 4.0.0 ขึ้นไปขยายเครื่องมือ Desugaring ให้ Desugar API ภาษา Java ด้วย คุณสามารถรวม 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}
  • Optionals (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 ขึ้นไป ระบบจะรองรับ Java 11 API เพิ่มเติม เช่น java.nio.file บางส่วน

ดูรายการ API ที่รองรับทั้งหมดได้ที่ Java 8+ API ที่พร้อมใช้งานผ่านกระบวนการ Desugaring และ Java 11+ API ที่พร้อมใช้งานผ่านกระบวนการ Desugaring

เพื่อรองรับ API ภาษาเหล่านี้ ปลั๊กอินจะคอมไพล์ไฟล์ DEX แยกต่างหากซึ่งมีการติดตั้งใช้งาน API ที่ขาดหายไปและรวมไว้ในแอปของคุณ กระบวนการ Desugaring จะเขียนโค้ดของแอปใหม่เพื่อใช้ไลบรารีนี้แทนที่รันไทม์ ซอร์สโค้ดที่คอมไพล์เป็นไฟล์ DEX แยกต่างหากจะอยู่ในที่เก็บ GitHub desugar_jdk_libs

วิธีเปิดใช้การรองรับ API ภาษาเหล่านี้ในแพลตฟอร์ม Android เวอร์ชันใดก็ได้

  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 ภาษาเหล่านี้ (โดยตรงหรือผ่านโมดูลไลบรารีหรือทรัพยากร Dependency) เพื่อให้ APK ทดสอบที่มีการวัดคุมมี API ที่ขาดหายไป

  • คุณต้องการเรียกใช้ Lint ในโมดูลไลบรารีแยกต่างหาก ซึ่งจะช่วยให้ Lint จดจำการใช้งาน API ภาษาที่ถูกต้องและหลีกเลี่ยงการรายงานคำเตือนที่เป็นเท็จ

โปรดทราบว่ากระบวนการ Desugaring ของ 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 ในที่เก็บ GitHub desugar_jdk_libs