อย่างที่เรารู้กันว่า Core Framework ของระบบปฏิบัติการณ์แอนดรอยด์นั้นใช้ภาษา Java เป็นหลัก จึงเป็นเหตุผลว่าทำไมการพัฒนาแอปบนแอนดรอยด์ด้วย Native Framework จะต้องเป็นภาษา Java (หรือ Kotlin ก็ได้นะ) และเมื่อพูดถึงภาษา Java ก็นับว่าเป็น Programming Language ยอดนิยมตัวหนึ่งที่ในปัจจุบันก็ถูกพัฒนาเป็น Java 17 กันแล้ว

บทความนี้เจาะจงไปที่ภาษา Java ก็จริง แต่ก็เป็นเรื่องราวที่มีผลสำหรับผู้ใช้ที่ใช้ภาษา Kotlin ด้วยเช่นกัน

ถึงแม้ว่าในปัจจุบันจะมี Java 17 ให้ใช้งานกันแล้ว แต่แอนดรอยด์ยังคงใช้เวอร์ชันเก่าอยู่ และ​มี API ให้ใช้งานแค่บางส่วนด้วย (เพราะบางตัวไม่จำเป็นสำหรับการทำงานของแอนดรอยด์)

Language Feature ของ Java บนแอนดรอยด์แต่ละเวอร์ชัน

ถ้าอิงจาก API Level 21 ที่เป็น Minimum SDK Version สำหรับหลาย ๆ แอปในปัจจุบัน จะอยู่ที่ Java 7 เป็นหลัก (ในยุคแรก ๆ ใช้ Java 6) และในแอนดรอยด์แต่ละเวอร์ชันใหม่ ๆ ก็อาจจะมาพร้อมกับการรองรับคำสั่งของ Java เวอร์ชันใหม่ ๆ ด้วยเช่นกัน

  • Java 8 : Android 7.0 Nougat (API Level 24) - Android 8.0 Oreo (API Level 26)
  • Java 9 : Android 11 (API Level 30)
  • Java 10 : Android 12 (API Level 31)
  • Java 11 : Android 13 (API Level 33)

และเมื่อต้องพัฒนาแอปให้รองรับกับแอนดรอยด์หลายเวอร์ชัน จึงทำให้นักพัฒนาไม่สามารถใช้งานคำสั่งที่อยู่ใน Java เวอร์ชันใหม่ ๆ ได้ เพราะแอนดรอยด์เวอร์ชันเก่าจะไม่รู้จักคำสั่งดังกล่าวและทำให้แอปพังทันที

แก้ปัญหาดังกล่าวด้วย Desugar ของ D8/R8

เพื่อทำให้นักพัฒนาสามารถเรียกใช้งาน Language Feature ของ Java เวอร์ชันใหม่ ๆ โดยที่คำสั่งดังกล่าวสามารถทำงานบนแอนดรอยด์เวอร์ชันที่เก่ากว่าได้ จึงทำให้ทีมแอนดรอยด์ได้พัฒนาความสามารถที่เรียกว่า Desugar เพิ่มเข้าไปใน D8 ที่เป็น Dex Compiler

D8 เป็น Dex Compiler ถูกนำมาใช้แทน DX อย่างเป็นทางการใน Android Studio 3.2

โดย Desugar จะทำหน้าที่แปลง Bytecode (Bytecode Transformation) ที่เป็นโค้ดของ Java เวอร์ชัน 8 ขึ้นไป ให้อยู่ในรูปแบบคำสั่งที่สามารถทำงานใน Java เวอร์ชันต่ำกว่าได้ (เรียกขั้นตอนนี้ว่า Desugaring) โดยแลกกับ Build Time ที่นานขึ้นนิดหน่อย

จึงทำให้นักพัฒนาแอนดรอยด์ในปัจจุบันสามารถใช้งาน Language Feature ที่อยู่ใน Java เวอร์ชันใหม่ ๆ ได้ง่ายขึ้น ไม่ต้องกังวลว่าจะมีปัญหาในแอนดรอยด์เวอร์ชันเก่า

การเปิดใช้งาน Desugar ในโปรเจคบน Android Studio

ในการเปิดใช้งาน Desugar จะแบ่งออกเป็น 2 แบบ ระหว่าง Java 8 Language Feature และ Java 8+ Language Feature โดยขึ้นอยู่กับคำสั่งที่มีให้เรียกใช้งาน

Java 8 Language Feature

  • Lambda Expressions
  • Method References
  • Type Annotations
  • Default and Static Interface Methods
  • Repeating Annotations

Java 8+ Language Feature

ที่ต้องแยกแบบนี้ เพราะในยุคแรก ๆ นั้น Desugar จะรองรับแค่ Java 8 Language Feature เท่านั้น แต่ในปัจจุบัน Desugar สามารถรองรับ Core Library Desugaring แล้ว จึงมี Java 8+ Language Feature เพิ่มเข้ามาด้วย

สำหรับ Java 8 Language Feature

โดยปกติการสร้างโปรเจคใหม่ ๆ บน Android Studio เวอร์ชันล่าสุดจะเปิดใช้งาน Java 8 Language Feature ให้อยู่แล้ว ดังนั้นนักพัฒนาแทบจะไม่ต้องทำอะไรเพิ่ม แต่สำหรับโปรเจคเก่าจะมีเงื่อนไขว่าต้องใช้ Android Gradle Plugin (AGP) เวอร์ชัน 3.0.0 ขึ้นไปด้วย

บางคำสั่งในภาษา Kotlin ก็ต้องเปิดใช้งาน Java 8 Language Feature ถึงจะเรียกใช้งานได้

จากนั้นให้เปิด build.gradle ของ Module ที่ต้องการทำให้รองรับ Java 8 Langauge Feature ขึ้นมา แล้วเพิ่ม compileOptions และ kotlinOptions (ถ้าใช้ Kotlin ด้วย) ไว้ข้างใน android แบบนี้

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

จากนั้นให้ Sync Gradle ใหม่ แล้วลองทดสอบดูก็จะพบว่าสามารถใช้คำสั่งที่อยู่ใน Java 8 Language Feature ได้แล้ว

สำหรับ Java 8+ Language Feature

ในการใช้งาน Java 8+ Language Feature จะต้องเปิดใช้งานเอง และในโปรเจคจะต้องใช้ AGP เวอร์ชัน 4.0.0 ขึ้นไปด้วย

ให้เปิด build.gradle ของ Module ที่ต้องการทำให้รองรับ Java 8+ Language Feature ขึ้นมา แล้วเพิ่ม Library และเปิดใช้งาน Core Library Desugaring แบบนี้

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
        coreLibraryDesugaringEnabled true
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}

จากนั้นให้ Sync Gradle ใหม่ แล้วลองทดสอบดูก็จะพบว่าสามารถใช้คำสั่งที่อยู่ใน Java 8+ Language Feature ได้แล้ว

สรุป

ถึงแม้ว่าแอนดรอยด์จะมีการพัฒนาและเพิ่มฟีเจอร์ใหม่อยู่ตลอดเวลา แต่ Java ที่ใช้ใน Core Framework ยังคงเป็นเวอร์ชันเก่าอยู่เมื่อเทียบกับ Java เวอร์ชันล่าสุด และด้วยความแตกต่างของ Java Version ที่อยู่ในแอนดรอยด์แต่ละเวอร์ชันทำให้ทีมแอนดรอยด์สร้าง Desugar ขึ้นมาเพื่อช่วยทำให้นักพัฒนาสามารถใช้คำสั่งใน Java เวอร์ชันใหม่ ๆ บนแอนดรอยด์เวอร์ชันเก่าได้

ซึ่งเอาเข้าจริงชุดคำสั่งที่มีให้ใช้งานก็เพียงพอสำหรับการพัฒนาแอปบนแอนดรอยด์อยู่แล้ว และเมื่อใช้ภาษา Kotlin แทน ก็ยิ่งทำให้ความสำคัญของ Feature Language ในเวอร์ชันใหม่จำเป็นน้อยลงไปอีก เพราะเพียงแค่เปิดใช้งาน Java 8 Feature Language ก็เพียงพอต่อการใช้ภาษา Kotlin แล้ว

แหล่งข้อมูลอ้างอิง