คำแนะนำในการย้ายข้อมูล AndroidX Media3

แอปที่ใช้ไลบรารี com.google.android.exoplayer2 แบบสแตนด์อโลนและ androidx.media อยู่ในขณะนี้ควรย้ายข้อมูลไปยัง androidx.media3 ใช้สคริปต์การย้ายข้อมูลเพื่อย้ายข้อมูลไฟล์บิลด์ Gradle, ไฟล์ต้นฉบับ Java และ Kotlin รวมถึงไฟล์เลย์เอาต์ XML จาก ExoPlayer2.19.1 ไปยัง AndroidX Media3 1.1.1

ภาพรวม

ก่อนย้ายข้อมูล โปรดอ่านส่วนต่อไปนี้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิประโยชน์ของ API ใหม่, API ที่จะย้าย และข้อกําหนดเบื้องต้นที่โปรเจ็กต์ของแอปควรมีคุณสมบัติตรงตาม

เหตุผลที่ควรย้ายข้อมูลไปยัง Jetpack Media3

  • ซึ่งเป็นบ้านหลังใหม่ของ ExoPlayer ส่วน com.google.android.exoplayer2 ได้ปิดให้บริการแล้ว
  • เข้าถึง Player API ในคอมโพเนนต์/กระบวนการต่างๆ ด้วย MediaBrowser/MediaController
  • ใช้ความสามารถเพิ่มเติมของ MediaSession และ MediaController API
  • โฆษณาความสามารถในการเล่นด้วยการควบคุมการเข้าถึงแบบละเอียด
  • ลดความซับซ้อนของแอปโดยนำ MediaSessionConnector และ PlayerNotificationManager ออก
  • เข้ากันได้แบบย้อนหลังกับ API ไคลเอ็นต์ที่เข้ากันได้กับสื่อ (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

Media API เพื่อย้ายข้อมูลไปยัง AndroidX Media3

  • ExoPlayer และส่วนขยาย
    ซึ่งรวมถึงโมดูลทั้งหมดของโปรเจ็กต์ ExoPlayer เดิม ยกเว้นโมดูล mediasession ที่ถูกยกเลิก คุณย้ายข้อมูลแอปหรือโมดูลต่างๆ ที่ขึ้นอยู่กับแพ็กเกจใน com.google.android.exoplayer2 ได้ด้วยสคริปต์การย้ายข้อมูล
  • MediaSessionConnector (ขึ้นอยู่กับแพ็กเกจ androidx.media.* ของ androidx.media:media:1.4.3+)
    นำ MediaSessionConnector ออกและใช้ androidx.media3.session.MediaSession แทน
  • MediaBrowserServiceCompat (ขึ้นอยู่กับ androidx.media.* แพ็กเกจ androidx.media:media:1.4.3+)
    ย้ายข้อมูลคลาสย่อยของ androidx.media.MediaBrowserServiceCompat ไปยัง androidx.media3.session.MediaLibraryService และโค้ดโดยใช้ MediaBrowserCompat.MediaItem ไปยัง androidx.media3.common.MediaItem
  • MediaBrowserCompat (ขึ้นอยู่กับ android.support.v4.media.* แพ็กเกจ androidx.media:media:1.4.3+)
    ย้ายข้อมูลโค้ดไคลเอ็นต์โดยใช้ MediaBrowserCompat หรือ MediaControllerCompat เพื่อใช้ androidx.media3.session.MediaBrowser กับ androidx.media3.common.MediaItem

สิ่งที่ต้องมีก่อน

  1. ตรวจสอบว่าโปรเจ็กต์อยู่ภายใต้การควบคุมแหล่งที่มา

    ตรวจสอบว่าคุณเปลี่ยนกลับการเปลี่ยนแปลงที่เครื่องมือย้ายข้อมูลที่ใช้สคริปต์ทำได้ง่าย หากโปรเจ็กต์ของคุณยังไม่อยู่ภายใต้การควบคุมแหล่งที่มา ตอนนี้เป็นโอกาสที่ดีในการเริ่มต้นใช้งาน หากไม่ต้องการทําเช่นนั้นด้วยเหตุผลใดก็ตาม ให้ทําสําเนาสำรองของโปรเจ็กต์ก่อนเริ่มการย้ายข้อมูล

  2. อัปเดตแอป

    • เราขอแนะนำให้อัปเดตโปรเจ็กต์ของคุณให้ใช้ไลบรารี ExoPlayer เวอร์ชันล่าสุดและนำการเรียกวิธีการที่เลิกใช้งานแล้วออก หากต้องการใช้สคริปต์ในการย้ายข้อมูล คุณต้องจับคู่เวอร์ชันที่จะอัปเดตกับเวอร์ชันที่สคริปต์จัดการ

    • เพิ่ม compileSdkVersion ของแอปเป็นอย่างน้อย 32

    • อัปเกรด Gradle และปลั๊กอิน Gradle ของ Android Studio เป็นเวอร์ชันล่าสุดที่ทำงานร่วมกับ Dependency ที่อัปเดตจากด้านบนได้ เช่น

      • เวอร์ชันปลั๊กอิน Android Gradle: 7.1.0
      • เวอร์ชัน Gradle: 7.4
    • แทนที่คำสั่งการนําเข้าที่ใช้ไวลด์การ์ดทั้งหมดที่ใช้เครื่องหมายดอกจัน (*) และใช้คำสั่งการนําเข้าแบบเต็มที่: ลบคำสั่งการนําเข้าที่ใช้ไวลด์การ์ด และใช้ Android Studio นําเข้าคำสั่งแบบเต็มที่ (F2 - Alt/Enter, F2 - Alt/Enter, ...)

    • ย้ายข้อมูลจาก com.google.android.exoplayer2.PlayerView ไปยัง com.google.android.exoplayer2.StyledPlayerView ซึ่งจำเป็นต้องทำเนื่องจากไม่มีค่าเทียบเท่าสำหรับ com.google.android.exoplayer2.PlayerView ใน AndroidX Media3

ย้ายข้อมูล ExoPlayer ที่รองรับสคริปต์

สคริปต์นี้ช่วยให้การย้ายจาก com.google.android.exoplayer2 ไปยังโครงสร้างแพ็กเกจและโมดูลใหม่ภายใต้ androidx.media3 เป็นไปอย่างง่ายดาย สคริปต์จะใช้การตรวจสอบความถูกต้องบางอย่างในโปรเจ็กต์และพิมพ์คำเตือนหากการตรวจสอบไม่สำเร็จ ไม่เช่นนั้น ระบบจะใช้การแมปคลาสและแพ็กเกจที่เปลี่ยนชื่อในแหล่งข้อมูลของโปรเจ็กต์ Gradle ของ Android ที่เขียนด้วย Java หรือ Kotlin

usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
 PROJECT_ROOT: path to your project root (location of 'gradlew')
 -p: list package mappings and then exit
 -c: list class mappings (precedence over package mappings) and then exit
 -d: list dependency mappings and then exit
 -l: list files that will be considered for rewrite and then exit
 -x: exclude the path from the list of file to be changed: 'app/src/test'
 -m: migrate packages, classes and dependencies to AndroidX Media3
 -f: force the action even when validation fails
 -v: print the exoplayer2/media3 version strings of this script
 -h, --help: show this help text

การใช้สคริปต์การย้ายข้อมูล

  1. ดาวน์โหลดสคริปต์การย้ายข้อมูลจากแท็กของโปรเจ็กต์ ExoPlayer ใน GitHub ตามเวอร์ชันที่คุณใช้อัปเดตแอป ดังนี้

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. ทำให้สคริปต์เป็นไฟล์ปฏิบัติการ ดังนี้

    chmod 744 media3-migration.sh
    
  3. เรียกใช้สคริปต์ด้วย --help เพื่อดูข้อมูลเกี่ยวกับตัวเลือก

  4. เรียกใช้สคริปต์ด้วย -l เพื่อแสดงชุดไฟล์ที่เลือกสำหรับการย้ายข้อมูล (ใช้ -f เพื่อบังคับให้แสดงรายการโดยไม่มีคำเตือน)

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. เรียกใช้สคริปต์ด้วย -m เพื่อแมปแพ็กเกจ ชั้นเรียน และโมดูลกับ Media3 การเรียกใช้สคริปต์ด้วยตัวเลือก -m จะนำการเปลี่ยนแปลงไปใช้กับไฟล์ที่เลือก

    • หยุดเมื่อพบข้อผิดพลาดในการตรวจสอบโดยไม่ทําการเปลี่ยนแปลง
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • การบังคับใช้

    หากสคริปต์พบการละเมิดข้อกําหนดเบื้องต้น คุณสามารถบังคับใช้การย้ายข้อมูลด้วย Flag -f ดังนี้

    ./media3-migration.sh -m -f /path/to/gradle/project/root
    
 # list files selected for migration when excluding paths
 ./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
 # migrate the selected files
 ./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root

ทําตามขั้นตอนเหล่านี้ด้วยตนเองหลังจากเรียกใช้สคริปต์ด้วยตัวเลือก -m

  1. ตรวจสอบวิธีที่สคริปต์เปลี่ยนโค้ด: ใช้เครื่องมือเปรียบเทียบและแก้ไขปัญหาที่อาจเกิดขึ้น (พิจารณาส่งข้อบกพร่องหากคุณคิดว่าสคริปต์มีปัญหาทั่วไปซึ่งเกิดขึ้นโดยไม่ส่งผ่านตัวเลือก -f)
  2. สร้างโปรเจ็กต์: ใช้ ./gradlew clean build หรือใน Android Studio ให้เลือกไฟล์ > ซิงค์โปรเจ็กต์กับไฟล์ Gradle จากนั้นเลือกสร้าง > ล้างโปรเจ็กต์ แล้วเลือกสร้าง > สร้างโปรเจ็กต์อีกครั้ง (ตรวจสอบการสร้างในแท็บ "สร้าง - เอาต์พุตการสร้าง" ของ Android Studio

ขั้นตอนติดตามผลที่แนะนำ

  1. แก้ไขปัญหาเลือกใช้ข้อผิดพลาดเกี่ยวกับการใช้ API ที่ไม่เสถียร
  2. แทนที่การเรียก API ที่เลิกใช้งานแล้ว: ใช้ API ทดแทนที่แนะนำ ชี้เมาส์ไว้เหนือคำเตือนใน Android Studio และดู JavaDoc ของสัญลักษณ์ที่เลิกใช้งานแล้วเพื่อดูว่าจะใช้อะไรแทนการเรียกนั้นๆ
  3. จัดเรียงคำสั่งการนําเข้า: เปิดโปรเจ็กต์ใน Android Studio แล้วคลิกขวาที่โหนดโฟลเดอร์แพ็กเกจในเครื่องมือดูโปรเจ็กต์ แล้วเลือกเพิ่มประสิทธิภาพการนําเข้าในแพ็กเกจที่มีไฟล์ต้นทางที่เปลี่ยนแปลง

แทนที่ MediaSessionConnector ด้วย androidx.media3.session.MediaSession

ใน MediaSessionCompat รุ่นเดิม MediaSessionConnector มีหน้าที่รับผิดชอบในการซิงค์สถานะของเพลเยอร์กับสถานะของเซสชัน รวมถึงรับคําสั่งจากตัวควบคุมที่ต้องมอบสิทธิ์ให้กับเมธอดที่เหมาะสมของเพลเยอร์ เมื่อใช้ AndroidX Media3 การดำเนินการนี้จะทำโดย MediaSession โดยตรงโดยไม่ต้องใช้เครื่องมือเชื่อมต่อ

  1. นําการอ้างอิงและการใช้งาน MediaSessionConnector ทั้งหมดออก: หากคุณใช้สคริปต์อัตโนมัติเพื่อย้ายข้อมูลคลาสและแพ็กเกจ ExoPlayer ก็มีความเป็นไปได้ที่สคริปต์จะทําให้โค้ดของคุณอยู่ในสถานะที่คอมไพล์ไม่ได้เนื่องจากMediaSessionConnectorที่แก้ไขไม่ได้ Android Studio จะแสดงโค้ดที่ไม่ถูกต้องเมื่อคุณพยายามสร้างหรือเริ่มแอป

  2. ในไฟล์ build.gradle ที่คุณดูแลรักษา Dependency ให้เพิ่มDependency การใช้งานไปยังโมดูลเซสชัน AndroidX Media3 และนํา Dependency แบบเดิมออก ดังนี้

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. แทนที่ MediaSessionCompat ด้วย androidx.media3.session.MediaSession

  4. ในเว็บไซต์โค้ดที่คุณสร้าง MediaSessionCompat รุ่นเดิม ให้ใช้ androidx.media3.session.MediaSession.Builder เพื่อสร้าง MediaSession ส่งโปรแกรมเล่น เพื่อสร้างเครื่องมือสร้างเซสชัน

    val player = ExoPlayer.Builder(context).build()
    mediaSession = MediaSession.Builder(context, player)
        .setSessionCallback(MySessionCallback())
        .build()
    
  5. ใช้ MySessionCallback ตามที่จำเป็นสำหรับแอปของคุณ (ไม่บังคับ) หากต้องการอนุญาตให้ตัวควบคุมเพิ่มรายการสื่อลงในโปรแกรมเล่น ให้ใช้ MediaSession.Callback.onAddMediaItems() ซึ่งให้บริการเมธอด API ในปัจจุบันและเดิมหลายรายการที่เพิ่มรายการสื่อลงในเพลเยอร์เพื่อเล่นในลักษณะที่เข้ากันได้แบบย้อนหลัง ซึ่งรวมถึงMediaController.set/addMediaItems()เมธอดของตัวควบคุม Media3 และTransportControls.prepareFrom*/playFrom*เมธอดของ API รุ่นเดิม ตัวอย่างการติดตั้งใช้งาน onAddMediaItems จะอยู่ใน PlaybackService ของแอปเดโมเซสชัน

  6. ปล่อยเซสชันสื่อในเว็บไซต์โค้ดที่คุณทำลายเซสชันของคุณก่อนการย้ายข้อมูล โดยทำดังนี้

    mediaSession?.run {
      player.release()
      release()
      mediaSession = null
    }
    

ฟังก์ชันการทำงานของ MediaSessionConnector ใน Media3

ตารางต่อไปนี้แสดง Media3 API ที่จัดการฟังก์ชันการทำงานซึ่งก่อนหน้านี้ติดตั้งใช้งานใน MediaSessionConnector

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setCustomLayout()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() เรียกใช้ภายใน)
QueueNavigator ForwardingPlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

ย้ายข้อมูล MediaBrowserService ไปยัง MediaLibraryService

AndroidX Media3 เปิดตัว MediaLibraryService ที่จะแทนที่ MediaBrowserServiceCompat JavaDoc ของ MediaLibraryService และคลาสซุปเปอร์คลาส MediaSessionService จะให้ข้อมูลเบื้องต้นที่ดีเกี่ยวกับ API และรูปแบบการเขียนโปรแกรมแบบแอซิงโครนัสของบริการ

MediaLibraryService เข้ากันได้แบบย้อนหลังกับ MediaBrowserService แอปไคลเอ็นต์ที่ใช้ MediaBrowserCompat หรือ MediaControllerCompat จะทำงานต่อไปโดยไม่มีการเปลี่ยนแปลงโค้ดเมื่อเชื่อมต่อกับ MediaLibraryService ลูกค้าจะทราบได้อย่างชัดเจนว่าแอปของคุณใช้ MediaLibraryService หรือ MediaBrowserServiceCompat รุ่นเดิม

แผนภาพคอมโพเนนต์ของแอปพร้อมบริการ กิจกรรม และแอปภายนอก
รูปที่ 1: ภาพรวมคอมโพเนนต์ของแอปสื่อ
  1. หากต้องการให้ใช้งานร่วมกันได้ คุณจะต้องลงทะเบียนทั้ง 2 อินเทอร์เฟซบริการกับบริการใน AndroidManifest.xml วิธีนี้จะช่วยให้ลูกค้าพบบริการของคุณตามอินเทอร์เฟซบริการที่จำเป็น

    <service android:name=".MusicService" android:exported="true">
        <intent-filter>
            <action android:name="androidx.media3.session.MediaLibraryService"/>
            <action android:name="android.media.browse.MediaBrowserService" />
        </intent-filter>
    </service>
    
  2. ในไฟล์ build.gradle ที่คุณดูแลรักษา Dependency ให้เพิ่มDependency การใช้งานในโมดูลเซสชัน AndroidX Media3 และนํา Dependency แบบเดิมออก

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. เปลี่ยนบริการให้รับค่าจาก MediaLibraryService แทน MediaBrowserService ดังที่ได้กล่าวไว้ก่อนหน้านี้ MediaLibraryService เข้ากันได้กับ MediaBrowserService รุ่นเดิม ดังนั้น API ที่กว้างขึ้นซึ่งบริการเสนอให้กับลูกค้าจะยังคงเหมือนเดิม จึงมีแนวโน้มที่แอปจะสามารถเก็บตรรกะที่จำเป็นส่วนใหญ่ที่จำเป็นต่อการปรับใช้ MediaBrowserService และปรับเปลี่ยนให้เหมาะกับ MediaLibraryService ใหม่ได้

    ความแตกต่างหลักเมื่อเทียบกับ MediaBrowserServiceCompat เดิมมีดังนี้

    • ใช้วิธีการสำหรับอายุการใช้งานของบริการ: วิธีการที่จำเป็นต้องลบล้างในบริการคือ onCreate/onDestroy ซึ่งแอปจัดสรร/เผยแพร่เซสชันของไลบรารี โปรแกรมเล่น และทรัพยากรอื่นๆ นอกจากวิธีการเกี่ยวกับวงจรบริการมาตรฐานแล้ว แอปยังต้องลบล้าง onGetSession(MediaSession.ControllerInfo) เพื่อแสดง MediaLibrarySession ที่สร้างขึ้นใน onCreate

    • ใช้งาน MediaLibraryService.MediaLibrarySessionCallback: การสร้างเซสชันต้องมี MediaLibraryService.MediaLibrarySessionCallback ที่ใช้งานเมธอด API ของโดเมนจริง ดังนั้นแทนที่จะลบล้างเมธอด API ของบริการเดิม คุณจะลบล้างเมธอดของ MediaLibrarySession.Callback แทน

      จากนั้นระบบจะใช้การเรียกกลับเพื่อสร้าง MediaLibrarySession ดังนี้

      mediaLibrarySession =
            MediaLibrarySession.Builder(this, player, MySessionCallback())
               .build()
      

      ดู API แบบสมบูรณ์ของ MediaLibrarySessionCallback ในเอกสารประกอบของ API

    • ใช้ MediaSession.Callback.onAddMediaItems(): Callback onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) จะแสดงเมธอด API ต่างๆ ทั้งในปัจจุบันและแบบเดิมที่เพิ่มรายการสื่อไปยังโปรแกรมเล่นเพื่อการเล่นด้วยวิธีที่เข้ากันได้แบบย้อนหลัง ซึ่งรวมถึงMediaController.set/addMediaItems()เมธอดของเครื่องมือควบคุม Media3 และTransportControls.prepareFrom*/playFrom*เมธอดของ API เดิม ตัวอย่างการใช้งานการเรียกกลับจะอยู่ใน PlaybackService ของแอปสาธิตเซสชัน

    • AndroidX Media3 ใช้ androidx.media3.common.MediaItem แทน MediaBrowserCompat.MediaItem และ MediaMetadataCompat คุณต้องเปลี่ยนแปลงโค้ดบางส่วนที่เชื่อมโยงกับคลาสเดิมตามความเหมาะสม หรือแมปกับ Media3 MediaItem แทน

    • รูปแบบการเขียนโปรแกรมแบบแอซิงโครนัสทั่วไปเปลี่ยนเป็น Futures ซึ่งต่างจากแนวทาง Result แบบถอดออกได้ของ MediaBrowserServiceCompat การใช้งานบริการสามารถแสดงผลListenableFutureแบบแอซิงโครนัสแทนการแยกผลลัพธ์ หรือแสดงผล Future แบบทันทีเพื่อแสดงผลลัพธ์โดยตรง

นำ PlayerNotificationManager ออก

MediaLibraryService รองรับการแจ้งเตือนสื่อโดยอัตโนมัติ และคุณสามารถนำ PlayerNotificationManager ออกได้เมื่อใช้ MediaLibraryService หรือ MediaSessionService

แอปสามารถปรับแต่งการแจ้งเตือนได้โดยการตั้งค่า MediaNotification.Provider ที่กําหนดเองใน onCreate() ซึ่งจะแทนที่ DefaultMediaNotificationProvider จากนั้น MediaLibraryService จะเป็นผู้ดูแลการเริ่มบริการที่ทำงานอยู่เบื้องหน้าตามที่จำเป็น

การลบล้าง MediaLibraryService.updateNotification() จะทำให้แอปมีสิทธิ์เต็มรูปแบบในการโพสต์การแจ้งเตือนและเริ่ม/หยุดบริการที่ทำงานอยู่เบื้องหน้าได้ตามต้องการ

ย้ายข้อมูลโค้ดไคลเอ็นต์โดยใช้ MediaBrowser

เมื่อใช้ AndroidX Media3 MediaBrowser จะใช้อินเทอร์เฟซ MediaController/Player และสามารถใช้เพื่อควบคุมการเล่นสื่อได้นอกเหนือจากการเรียกดูคลังสื่อ หากเคยสร้าง MediaBrowserCompat และ MediaControllerCompat ในโลกเดิม คุณจะทำแบบเดียวกันได้โดยใช้ MediaBrowser ใน Media3 เท่านั้น

มากขึ้น

คุณสร้าง MediaBrowser และรอการเชื่อมต่อกับบริการได้ดังนี้

scope.launch {
    val sessionToken =
        SessionToken(context, ComponentName(context, MusicService::class.java)
    browser =
        MediaBrowser.Builder(context, sessionToken))
            .setListener(BrowserListener())
            .buildAsync()
            .await()
    // Get the library root to start browsing the library.
    root = browser.getLibraryRoot(/* params= */ null).await();
    // Add a MediaController.Listener to listen to player state events.
    browser.addListener(playerListener)
    playerView.setPlayer(browser)
}

ดูหัวข้อควบคุมการเล่นในเซสชันสื่อเพื่อดูวิธีสร้าง MediaController สำหรับการควบคุมการเล่นอยู่เบื้องหลัง

ขั้นตอนเพิ่มเติมและการล้างข้อมูล

ข้อผิดพลาดของ API ไม่เสถียร

หลังจากย้ายข้อมูลไปยัง Media3 คุณอาจเห็นข้อผิดพลาดเกี่ยวกับการใช้ API ที่ไม่เสถียร API เหล่านี้ปลอดภัยที่จะใช้ และข้อผิดพลาดเกี่ยวกับ Lint เป็นผลพลอยได้จากการรับประกันความเข้ากันได้ของไบนารีแบบใหม่ หากไม่จำเป็นต้องใช้ความเข้ากันได้ของไบนารีที่เข้มงวด คุณจะระงับข้อผิดพลาดเหล่านี้ได้อย่างปลอดภัยด้วยคำอธิบายประกอบ @OptIn

ฉากหลัง

ทั้ง ExoPlayer v1 หรือ v2 ไม่ได้ให้การรับประกันที่เข้มงวดเกี่ยวกับความเข้ากันได้ของไบนารีของไลบรารีระหว่างเวอร์ชันต่อๆ มา แพลตฟอร์ม ExoPlayer API ออกแบบมาให้ครอบคลุมมาก เพื่อให้แอปปรับแต่งการเล่นได้เกือบทุกแง่มุม เวอร์ชันต่อๆ ไปของ ExoPlayer จะมีการเปลี่ยนชื่อสัญลักษณ์หรือการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบเป็นครั้งคราว (เช่น วิธีการใหม่ๆ ที่จำเป็นบนอินเทอร์เฟซ) ในหลายกรณี เราลดปัญหาการหยุดชะงักเหล่านี้ด้วยการเปิดตัวสัญลักษณ์ใหม่ควบคู่ไปกับการนำสัญลักษณ์เก่าออกในบางเวอร์ชัน เพื่อให้นักพัฒนาแอปมีเวลาในการย้ายข้อมูลการใช้งาน แต่วิธีนี้ใช้ไม่ได้เสมอไป

การเปลี่ยนแปลงที่ทำให้เกิดข้อขัดข้องเหล่านี้ส่งผลให้ผู้ใช้ไลบรารี ExoPlayer v1 และ v2 พบปัญหา 2 ข้อ ดังนี้

  1. การอัปเกรดจากเวอร์ชันไปยัง ExoPlayer อาจทําให้โค้ดหยุดคอมไพล์
  2. แอปที่ขึ้นกับ ExoPlayer ทั้งโดยตรงและผ่านไลบรารีระดับกลางต้องตรวจสอบว่า Dependency ทั้ง 2 รายการเป็นเวอร์ชันเดียวกัน ไม่เช่นนั้นความเข้ากันไม่ได้ของไบนารีอาจส่งผลให้แอปขัดข้องขณะรันไทม์

การปรับปรุงใน Media3

Media3 รับประกันความเข้ากันได้ของไบนารีสําหรับชุดย่อยของแพลตฟอร์ม API ส่วนที่ไม่รับประกันความเข้ากันได้ของไบนารีจะมีเครื่องหมาย @UnstableApi การใช้สัญลักษณ์ API ที่ไม่เสถียรจะทำให้เกิดข้อผิดพลาดเกี่ยวกับ Lint เว้นแต่จะมีการกำกับเนื้อหาด้วย @OptIn

หลังจากย้ายข้อมูลจาก ExoPlayer v2 ไปยัง Media3 คุณอาจเห็นข้อผิดพลาดเกี่ยวกับ Lint ของ API ที่ไม่เสถียรจำนวนมาก ซึ่งอาจทำให้ดูเหมือนว่า Media3 "เสถียรน้อยกว่า" ExoPlayer v2 ไม่เป็นเช่นนั้น ส่วน "ไม่เสถียร" ของ Media3 API มีระดับความเสถียรเท่ากับทั้งแพลตฟอร์ม API ของ ExoPlayer v2 และไม่มีการรับประกันแพลตฟอร์ม Media3 API ที่เสถียรใน ExoPlayer v2 เลย ความแตกต่างคือตอนนี้ข้อผิดพลาด Lint จะแจ้งเตือนให้คุณทราบถึงความเสถียรในระดับต่างๆ

จัดการข้อผิดพลาดของ Lint API ที่ไม่เสถียร

ดูรายละเอียดเกี่ยวกับวิธีเขียนคำอธิบายประกอบการใช้ Java และ Kotlin ของ API ที่ไม่เสถียรด้วย @OptIn ได้ที่ส่วนการแก้ปัญหาเกี่ยวกับข้อผิดพลาด Lint เหล่านี้

API ที่เลิกใช้งานแล้ว

คุณอาจเห็นว่าการเรียก API ที่เลิกใช้งานแล้วมีการขีดฆ่าใน Android Studio เราขอแนะนำให้แทนที่การเรียกดังกล่าวด้วยทางเลือกที่เหมาะสม วางเมาส์เหนือสัญลักษณ์เพื่อดู JavaDoc ที่บอก API ที่จะใช้แทน

ภาพหน้าจอ: วิธีแสดง JavaDoc ด้วยวิธีการอื่นของเมธอดที่เลิกใช้งาน
รูปที่ 3: เคล็ดลับเครื่องมือของ JavaDoc ใน Android Studio จะแนะนำสัญลักษณ์อื่นแทนสัญลักษณ์ที่เลิกใช้งาน

ตัวอย่างโค้ดและแอปเดโม

  • แอปสาธิตเซสชัน AndroidX Media3 (อุปกรณ์เคลื่อนที่และ WearOS)
    • การทำงานที่กำหนดเอง
    • การแจ้งเตือน UI ของระบบ ปุ่มสื่อ/BT
    • การควบคุมการเล่นของ Google Assistant
  • UAMP: Android Media Player (branch media3) (อุปกรณ์เคลื่อนที่, AutomotiveOS)
    • การแจ้งเตือน UI ของระบบ, ปุ่มสื่อ/BT, การกลับมาเล่นอีกครั้ง
    • การควบคุมการเล่นของ Google Assistant/WearOS
    • AutomotiveOS: คําสั่งและการลงชื่อเข้าใช้ที่กําหนดเอง