Migrationsanleitung für AndroidX Media3

Apps, die derzeit die eigenständige com.google.android.exoplayer2 verwenden und androidx.media sollten zu androidx.media3 migriert werden. Verwenden Sie das Migrationsskript zum Migrieren von Gradle-Build-Dateien, Java und Kotlin-Quelldateien und XML-Layoutdateien aus ExoPlayer 2.19.1 zu AndroidX Media3 1.1.1.

Übersicht

Lesen Sie vor der Migration die folgenden Abschnitte, um mehr über die die Vorteile der neuen APIs, die zu migrierenden APIs und die Voraussetzungen die das Projekt Ihrer App erfüllen soll.

Vorteile der Migration zu Jetpack Media3

  • Es ist das neue Zuhause von ExoPlayer, während com.google.android.exoplayer2 die eingestellt.
  • Zugriff auf die Player API über Komponenten/Prozesse hinweg mit MediaBrowser/MediaController.
  • Nutzen Sie die erweiterten Funktionen von MediaSession und MediaController API verwenden können.
  • Sie können Wiedergabefunktionen mit detaillierter Zugriffssteuerung bewerben.
  • Vereinfache deine App, indem du MediaSessionConnector und PlayerNotificationManager.
  • Abwärtskompatibel mit media-compat-Client-APIs (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

Media APIs für die Migration zu AndroidX Media3

  • ExoPlayer und seine Erweiterungen
    Dies schließt alle Module des alten ExoPlayer-Projekts mit Ausnahme des Das Modul mediasession wurde eingestellt. Apps oder Module, je nachdem, Pakete in com.google.android.exoplayer2 können mit dem Migrationsskript.
  • MediaSessionConnector (je nach androidx.media.* Pakete mit androidx.media:media:1.4.3+)
    Entfernen Sie die MediaSessionConnector und verwenden Sie androidx.media3.session.MediaSession.
  • MediaBrowserServiceCompat (abhängig vom androidx.media.* Pakete mit androidx.media:media:1.4.3+)
    Abgeleitete Klassen von androidx.media.MediaBrowserServiceCompat migrieren zu androidx.media3.session.MediaLibraryService und Code mithilfe von MediaBrowserCompat.MediaItem bis androidx.media3.common.MediaItem.
  • MediaBrowserCompat (abhängig vom android.support.v4.media.* Pakete mit androidx.media:media:1.4.3+)
    Migrieren Sie den Clientcode mit der MediaBrowserCompat oder MediaControllerCompat, um androidx.media3.session.MediaBrowser zu verwenden mit androidx.media3.common.MediaItem.

Voraussetzungen

  1. Prüfen, ob Ihr Projekt der Versionsverwaltung unterliegt

    Stellen Sie sicher, dass Sie Änderungen, die mit skriptbasierten Migrationstools angewendet wurden, einfach rückgängig machen können. Wenn Ihr Projekt noch nicht in der Versionsverwaltung ist, ist jetzt ein guter Zeitpunkt, um damit zu beginnen. Wenn Sie das aus irgendeinem Grund nicht tun möchten, Sicherungskopie Ihres Projekts erstellen, bevor Sie mit der Migration beginnen.

  2. App aktualisieren

    • Wir empfehlen Ihnen, Ihr Projekt auf die neueste Version der ExoPlayer-Bibliothek zu laden und alle Aufrufe verworfener Methoden. Wenn Sie das Skript für die Migration verwenden, müssen Sie es mit dem Version aktualisieren, auf die Sie mit der Version aktualisieren, die vom Skript verarbeitet wird.

    • Erhöhen Sie die compileSdkVersion Ihrer App auf mindestens 32.

    • Aktualisiere Gradle und das Android Studio-Gradle-Plug-in auf eine aktuelle Version von Gradle. die mit den oben aufgeführten aktualisierten Abhängigkeiten funktioniert. Für Instanz:

      • Android-Gradle-Plug-in, Version 7.1.0
      • Gradle-Version: 7.4
    • Alle Platzhalter-Importanweisungen ersetzen, die ein Sternchen verwenden (*) und voll qualifizierte Importanweisungen verwenden: Platzhalter löschen Anweisungen importieren und mithilfe von Android Studio die vollständig qualifizierten Anweisungen (F2 - Alt/Eingabetaste, F2 - Alt/Eingabetaste, ...).

    • Von com.google.android.exoplayer2.PlayerView zu migrieren com.google.android.exoplayer2.StyledPlayerView Das ist notwendig denn es gibt kein Äquivalent zu com.google.android.exoplayer2.PlayerView in AndroidX Media3.

ExoPlayer mit Skriptunterstützung migrieren

Das Skript erleichtert den Wechsel von com.google.android.exoplayer2 zum neuen Paket- und Modulstruktur unter androidx.media3. Das Skript wendet einige Validierungsprüfungen für Ihr Projekt und gibt Warnungen aus, wenn die Validierung fehlschlägt. Andernfalls werden die Zuordnungen von umbenannten Klassen und Paketen im Ressourcen eines Android-Gradle-Projekts, das in Java oder Kotlin geschrieben wurde.

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

Migrationsskript verwenden

  1. Laden Sie das Migrationsskript aus dem Tag des ExoPlayer-Projekts herunter auf GitHub für die Version, auf die Sie Ihre Anwendung aktualisiert haben:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. Machen Sie das Skript ausführbar:

    chmod 744 media3-migration.sh
    
  3. Führen Sie das Skript mit --help aus, um mehr über die Optionen zu erfahren.

  4. Führen Sie das Skript mit -l aus, um den Satz Dateien aufzulisten, die ausgewählt sind für Migration (verwenden Sie -f, um die Auflistung ohne Warnungen zu erzwingen):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. Führen Sie das Skript mit -m aus, um Pakete, Klassen und Module Media3 zuzuordnen. Wenn Sie das Skript mit der Option -m ausführen, werden Änderungen auf die ausgewählte -Dateien.

    • Bei Validierungsfehler stoppen, ohne Änderungen vorzunehmen
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • Erzwungene Ausführung

    Wenn das Skript einen Verstoß gegen die Voraussetzungen feststellt, kann die Migration mit dem Flag -f erzwungen:

    ./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

Führen Sie nach der Ausführung des Skripts mit der Option -m die folgenden manuellen Schritte aus:

  1. Prüfen, wie der Code durch das Skript geändert wurde: Verwenden Sie ein diff-Tool und beheben Sie das Problem. Mögliche Probleme. Wenn Sie der Meinung sind, dass im Skript ein Fehler vorliegt, allgemeines Problem, das aufgetreten ist, ohne die Option -f zu übergeben.
  2. Erstellen Sie das Projekt: Verwenden Sie entweder ./gradlew clean build oder Android. Wählen Sie in Studio File > Synchronisiere das Projekt mit Gradle Files und wähle dann Build > Projekt bereinigen und klicken Sie dann auf Build > Projekt neu erstellen (überwachen Sie Ihren Build im „Build – Build-Ausgabe“ von Android Studio.

Empfohlene weitere Schritte:

  1. Beheben Sie Opt-in-Fehler bei der Verwendung instabiler APIs.
  2. Veraltete API-Aufrufe ersetzen: Verwenden Sie die vorgeschlagene Ersatz-API. Bewegen Sie den Mauszeiger über die Warnung in Android Studio und lesen Sie JavaDoc des veralteten Symbols ein, um herauszufinden, was Sie anstelle eines bestimmten Aufrufs verwenden können.
  3. Importanweisungen sortieren: Öffne das Projekt in Android Studio und Klicken Sie in der Projektanzeige mit der rechten Maustaste auf einen Paketordnerknoten und wählen Sie Optimieren Sie die Importe für die Pakete, die die geänderten Quelldateien enthalten.

MediaSessionConnector durch androidx.media3.session.MediaSession ersetzen

In der alten MediaSessionCompat-Welt war MediaSessionConnector verantwortlich für die Synchronisierung des Status des Players mit dem Status der Sitzung und Befehle von Controllern empfangen, die eine Delegation an geeignete Player-Methoden. Bei AndroidX Media3 geschieht dies direkt von MediaSession. ohne einen Connector zu benötigen.

  1. Alle Verweise und Nutzung von MediaSessionConnector entfernen:Falls Sie dem automatisierten Skript zur Migration der ExoPlayer-Klassen und -Pakete, dann das hat Ihr Code wahrscheinlich einen nicht kompilierbaren Zustand bezüglich MediaSessionConnector, die nicht aufgelöst werden können. Android Studio wird den fehlerhaften Code anzuzeigen, wenn Sie versuchen, die App zu erstellen oder zu starten.

  2. Fügen Sie in der Datei build.gradle, in der Sie Ihre Abhängigkeiten verwalten, eine Implementierungsabhängigkeit vom AndroidX Media3-Sitzungsmodul der alten Abhängigkeit:

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. Ersetzen Sie MediaSessionCompat durch androidx.media3.session.MediaSession

  4. Verwenden Sie auf der Codewebsite, auf der Sie die alte MediaSessionCompat erstellt haben, Folgendes: androidx.media3.session.MediaSession.Builder, um MediaSession. Übergeben Sie den Player, um den Session-Builder zu erstellen.

    val player = ExoPlayer.Builder(context).build()
    mediaSession = MediaSession.Builder(context, player)
        .setSessionCallback(MySessionCallback())
        .build()
    
  5. Implementieren Sie MySessionCallback entsprechend Ihrer App. Dies ist optional. Wenn Controllern erlauben, Medieninhalte zum Player hinzuzufügen, MediaSession.Callback.onAddMediaItems() Sie dient verschiedenen aktuellen und alten API-Methoden, die Medienelemente zum Player hinzufügen, um sie in einem abwärtskompatibel sein. Dazu gehören die MediaController.set/addMediaItems()-Methoden des Media3-Controllers, wie sowie die TransportControls.prepareFrom*/playFrom* der Legacy-API. Eine Beispielimplementierung von onAddMediaItems kann findest du in der PlaybackService der Demo-App für die Session.

  6. Geben Sie die Mediensitzung auf der Code-Website frei, auf der Sie die Sitzung gelöscht haben. vor der Migration:

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

MediaSessionConnector-Funktion in Media3

In der folgenden Tabelle sehen Sie die Media3-APIs, die die Funktionen verwalten. zuvor in MediaSessionConnector implementiert.

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setCustomLayout()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() wird intern aufgerufen)
QueueNavigator ForwardingPlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

MediaBrowserService zu MediaLibraryService migrieren

AndroidX Media3 führt MediaLibraryService ein, das die MediaBrowserServiceCompat. Das JavaDoc von MediaLibraryService und seine Super- Die MediaSessionService-Klasse bieten eine gute Einführung in die API und den asynchrones Programmiermodell des Dienstes.

MediaLibraryService ist abwärtskompatibel mit dem MediaBrowserService. Eine Clientanwendung, die MediaBrowserCompat oder MediaControllerCompat, funktioniert auch ohne Codeänderungen beim Herstellen einer Verbindung in MediaLibraryService. Für einen Kunden ist es transparent, mit einem MediaLibraryService oder einem alten MediaBrowserServiceCompat.

<ph type="x-smartling-placeholder">
</ph> Diagramm der App-Komponenten mit Dienst, Aktivität und externen Apps
Abbildung 1: Medien-App-Komponente – Übersicht
  1. Damit die Abwärtskompatibilität funktioniert, müssen Sie beide Dienste registrieren, Schnittstellen mit Ihrem Dienst in der AndroidManifest.xml. Auf diese Weise Client findet Ihren Dienst über die erforderliche Dienstschnittstelle:

    <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. Fügen Sie in der Datei build.gradle, in der Sie Ihre Abhängigkeiten verwalten, eine von der Implementierungsabhängigkeit des AndroidX Media3-Sitzungsmoduls und entfernen Sie die alte Abhängigkeit:

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. Ändern Sie Ihren Dienst so, dass er von einer MediaLibraryService anstelle von MediaBrowserService Wie bereits erwähnt, ist MediaLibraryService mit der alten MediaBrowserService. Entsprechend ist die umfassendere API, die der Dienst umfasst, das Angebot für die Kundschaft unverändert ist. Es ist also wahrscheinlich, dass eine App der Großteil der Logik, die zum Implementieren von MediaBrowserService erforderlich ist, und passen es für das neue MediaLibraryService an.

    Die Hauptunterschiede zur Legacy-Version MediaBrowserServiceCompat sind:

    • Methoden für den Dienstlebenszyklus implementieren:Die Methoden, die ein im Dienst selbst überschrieben werden, onCreate/onDestroy, wobei ein App die Bibliothekssitzung, den Player und andere Elemente Ressourcen. Neben den Standardmethoden für den Dienstlebenszyklus muss für Rückgabe onGetSession(MediaSession.ControllerInfo) überschrieben werden das MediaLibrarySession, das in onCreate erstellt wurde.

    • MediaLibraryService.MediaLibrarySessionCallback implementieren: Erstellen für eine Sitzung MediaLibraryService.MediaLibrarySessionCallback implementiert, die eigentlichen Domain-API-Methoden. Anstatt die API-Methoden des alten Dienst verwenden, überschreiben Sie die Methoden des Stattdessen MediaLibrarySession.Callback.

      Der Callback wird dann zum Erstellen des MediaLibrarySession verwendet:

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

      Die vollständige API von MediaLibrarySessionCallback finden Sie in der API. Dokumentation.

    • MediaSession.Callback.onAddMediaItems() implementieren: Der Callback. onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) Ports verschiedene aktuelle und alte API-Methoden, die Medienelemente zum Player hinzufügen für die abwärtskompatible Wiedergabe. Dazu gehören die MediaController.set/addMediaItems()-Methoden des Media3-Controllers sowie die TransportControls.prepareFrom*/playFrom* der Legacy-API. Eine beispielhafte Implementierung des Callbacks kann Sie finden sie in der PlaybackService der Session-Demo-App.

    • AndroidX Media3 verwendet stattdessen androidx.media3.common.MediaItem von MediaBrowserCompat.MediaItem und MediaMetadataCompat. Bauteile Ihres Codes für die Legacy-Klassen müssen entsprechend geändert werden. oder dem Media3-MediaItem zuordnen.

    • Das allgemeine asynchrone Programmiermodell wurde in Futures im Gegensatz zum Ansatz Result des abnehmbaren MediaBrowserServiceCompat Ihre Dienstimplementierung kann Folgendes zurückgeben: ListenableFuture asynchron, anstatt ein Ergebnis oder ein sofortiges Future zurückgeben, um einen Wert direkt zurückzugeben.

PlayerNotificationManager entfernen

Die MediaLibraryService unterstützt Medienbenachrichtigungen automatisch und die PlayerNotificationManager kann entfernt werden, wenn ein MediaLibraryService- oder MediaSessionService

Eine App kann die Benachrichtigung anpassen, indem sie eine benutzerdefinierte MediaNotification.Provider in onCreate() ersetzt den DefaultMediaNotificationProvider MediaLibraryService kümmert sich dann um Starten des Dienstes im Vordergrund nach Bedarf.

Wenn Sie MediaLibraryService.updateNotification() überschreiben, kann eine App vollständige Verantwortung für das Posten einer Benachrichtigung und das Starten/Stoppen des Dienstes in im Vordergrund wie erforderlich.

Clientcode mit einem MediaBrowser migrieren

Bei AndroidX Media3 implementiert ein MediaBrowser die MediaController/Player Benutzeroberflächen und können verwendet werden, um nicht nur die Medien zu durchsuchen, sondern auch die Medienwiedergabe zu steuern. Bibliothek. Wenn Sie ein MediaBrowserCompat- und ein MediaControllerCompat können Sie dasselbe tun, indem Sie nur MediaBrowser in Media3.

Ein MediaBrowser kann erstellt werden und wartet auf die Verbindung zum erstellter Dienst:

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)
}

Werfen Sie einen Blick auf Wiedergabe in der Mediensitzung steuern , um zu erfahren, wie du ein MediaController zur Steuerung der Wiedergabe in der Hintergrund.

Weitere Schritte und Bereinigung

Instabile API-Fehler

Nach der Migration zu Media3 werden möglicherweise Lint-Fehler zu instabilen API-Nutzungen angezeigt. Diese APIs sind sicher und die Lint-Fehler sind ein Nebenprodukt der neuen Binärkompatibilität garantiert. Wenn Sie keine strikte Binärdatei benötigen Kompatibilität, können diese Fehler sicher mit einem @OptIn unterdrückt werden. .

Hintergrund

Weder ExoPlayer v1 noch v2 boten strikte Garantien hinsichtlich der Binärkompatibilität. der Bibliothek zwischen den nachfolgenden Versionen. Die ExoPlayer API-Oberfläche ist sehr groß, damit Apps nahezu jeden Aspekt Wiedergabe starten. In nachfolgenden Versionen von ExoPlayer wurden gelegentlich Symbole eingeführt. Umbenennungen oder andere funktionsgefährdende Änderungen (z.B. neue erforderliche Methoden für Schnittstellen). In In den meisten Fällen wurden diese Probleme durch die Einführung des neuen Symbols gemindert. und das alte Symbol für einige Versionen abgeschafft, ihre Nutzungsdaten zu migrieren, aber das war nicht immer möglich.

Diese funktionsgefährdenden Änderungen führten bei Nutzern von ExoPlayer v1 zu zwei Problemen und v2-Bibliotheken:

  1. Ein Upgrade von der ExoPlayer-Version kann dazu führen, dass die Kompilierung des Codes beendet wird.
  2. Eine App, die sowohl direkt als auch über eine Zwischenplattform von ExoPlayer abhängig war dass beide Abhängigkeiten dieselbe Version haben, Andernfalls könnten binäre Inkompatibilitäten zu Laufzeitabstürzen führen.

Verbesserungen bei Media3

Media3 garantiert die binäre Kompatibilität für einen Teil der API-Oberfläche. Die Teile, die keine binäre Kompatibilität garantieren, sind mit @UnstableApi Um diese Unterscheidung zu verdeutlichen, API-Symbole generieren einen Lint-Fehler, sofern sie nicht mit @OptIn gekennzeichnet sind.

Nach der Migration von ExoPlayer v2 zu Media3 Lint-Fehler. Das kann den Eindruck erwecken, dass Media3 „weniger stabil“ ist als ExoPlayer v2. Das ist nicht der Fall. „Instabil“ der Media3 API haben dieselben die Stabilität auf der gesamten Oberfläche der ExoPlayer v2 API und Garantien für die stabile Media3 API-Oberfläche sind in ExoPlayer v2 unter alle. Der Unterschied besteht darin, dass jetzt ein Lint-Fehler ein gewisses Maß an Stabilität.

Instabile API-Lint-Fehler verarbeiten

Im Abschnitt zur Fehlerbehebung zu diesen Lint-Fehlern erfahren Sie, wie Sie annotieren Sie die Java- und Kotlin-Verwendungen von instabilen APIs mit @OptIn.

Verworfene APIs

Aufrufe an eingestellte APIs sind in Android durchgestrichen. Studio Wir empfehlen, solche Aufrufe durch die entsprechende Alternative zu ersetzen. Bewegen Sie den Mauszeiger auf das Symbol, um das JavaDoc zu sehen, in dem angegeben wird, welche API stattdessen verwendet werden soll.

<ph type="x-smartling-placeholder">
</ph> Screenshot: Anzeige von JavaDoc mit einer alternativen Methode
Abbildung 3: JavaDoc-Kurzinfo in Android Studio schlägt eine Alternative für verworfene Symbole vor.

Codebeispiele und Demo-Apps

  • AndroidX Media3-Demo-App für Android-Sitzungen (Mobilgeräte und WearOS) <ph type="x-smartling-placeholder">
      </ph>
    • Benutzerdefinierte Aktionen
    • Benachrichtigung auf der System-Benutzeroberfläche, MediaButton/BT
    • Wiedergabesteuerung mit Google Assistant
  • UAMP: Android Media Player (branch media3) (Mobilgerät, AutomotiveOS) <ph type="x-smartling-placeholder">
      </ph>
    • Benachrichtigung auf der System-UI, MediaButton/BT, Wiederaufnahme der Wiedergabe
    • Wiedergabesteuerung mit Google Assistant und Wear OS
    • AutomotiveOS: benutzerdefinierter Befehl und Anmeldung