Apps, die derzeit die eigenständige com.google.android.exoplayer2-Bibliothek und androidx.media verwenden, sollten zu androidx.media3 migrieren. Verwenden Sie das Migrationsskript, um Gradle-Build-Dateien, Java- und Kotlin-Quelldateien sowie XML-Layoutdateien von ExoPlayer 2.19.1 zu AndroidX Media3 1.1.1 zu migrieren.
Übersicht
Lesen Sie sich vor der Migration die folgenden Abschnitte durch, um mehr über die Vorteile der neuen APIs, die zu migrierenden APIs und die Voraussetzungen zu erfahren, die das Projekt Ihrer App erfüllen sollte.
Warum zu Jetpack Media3 migrieren?
- Es ist die neue Heimat von ExoPlayer, während
com.google.android.exoplayer2eingestellt wird. - Greife mit
MediaBrowser/MediaControllerauf die Player API über Komponenten/Prozesse hinweg zu. - Verwenden Sie die erweiterten Funktionen der
MediaSession- undMediaController-API. - Wiedergabefunktionen mit detaillierter Zugriffssteuerung bewerben.
- Vereinfachen Sie Ihre App, indem Sie
MediaSessionConnectorundPlayerNotificationManagerentfernen. - Abwärtskompatibel mit media-compat-Client-APIs (
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)
Media APIs zur Migration zu AndroidX Media3
- ExoPlayer und seine Erweiterungen
Dazu gehören alle Module des alten ExoPlayer-Projekts mit Ausnahme des Moduls mediasession, das eingestellt wurde. Apps oder Module, die von Paketen incom.google.android.exoplayer2abhängen, können mit dem Migrationsskript migriert werden. - MediaSessionConnector (abhängig von den
androidx.media.*-Paketen vonandroidx.media:media:1.4.3+)
Entferne denMediaSessionConnectorund verwende stattdessen denandroidx.media3.session.MediaSession. - MediaBrowserServiceCompat (abhängig von den
androidx.media.*-Paketen vonandroidx.media:media:1.4.3+)
Migriere Unterklassen vonandroidx.media.MediaBrowserServiceCompatzuandroidx.media3.session.MediaLibraryServiceund Code, derMediaBrowserCompat.MediaItemverwendet, zuandroidx.media3.common.MediaItem. - MediaBrowserCompat (abhängig von den
android.support.v4.media.*-Paketen vonandroidx.media:media:1.4.3+)
Migriere den Clientcode mit demMediaBrowserCompatoderMediaControllerCompat, um denandroidx.media3.session.MediaBrowsermitandroidx.media3.common.MediaItemzu verwenden.
Vorbereitung
Projekt unter Quellcodeverwaltung stellen
Achten Sie darauf, dass Sie Änderungen, die durch skriptbasierte Migrationstools vorgenommen wurden, rückgängig machen können. Wenn Sie Ihr Projekt noch nicht unter Versionsverwaltung haben, ist jetzt ein guter Zeitpunkt, damit zu beginnen. Wenn Sie das aus irgendeinem Grund nicht tun möchten, erstellen Sie vor Beginn der Migration eine Sicherungskopie Ihres Projekts.
App aktualisieren
Wir empfehlen, Ihr Projekt auf die neueste Version der ExoPlayer-Bibliothek zu aktualisieren und alle Aufrufe von verworfenen Methoden zu entfernen. Wenn Sie das Skript für die Migration verwenden möchten, müssen Sie die Version, auf die Sie aktualisieren, mit der vom Skript verarbeiteten Version abgleichen.
Erhöhen Sie die compileSdkVersion Ihrer App auf mindestens 32.
Aktualisieren Sie Gradle und das Android Studio-Gradle-Plug-in auf eine aktuelle Version, die mit den oben genannten aktualisierten Abhängigkeiten funktioniert. Beispiel:
- Version des Android-Gradle-Plug-ins: 7.1.0
- Gradle-Version: 7.4
Ersetzen Sie alle Platzhalter-Importanweisungen, die ein Sternchen (*) verwenden, und verwenden Sie vollständig qualifizierte Importanweisungen: Löschen Sie die Platzhalter-Importanweisungen und verwenden Sie Android Studio, um die vollständig qualifizierten Anweisungen zu importieren (F2 – Alt/Eingabe, F2 – Alt/Eingabe, ...).
Von
com.google.android.exoplayer2.PlayerViewzucom.google.android.exoplayer2.StyledPlayerViewmigrieren Das ist erforderlich, weil es in AndroidX Media3 kein Äquivalent zucom.google.android.exoplayer2.PlayerViewgibt.
ExoPlayer mit Skriptunterstützung migrieren
Das Script erleichtert den Wechsel von com.google.android.exoplayer2 zur neuen Paket- und Modulstruktur unter androidx.media3. Das Script führt einige Validierungsprüfungen für Ihr Projekt durch und gibt Warnungen aus, wenn die Validierung fehlschlägt.
Andernfalls werden die Zuordnungen umbenannter Klassen und Pakete in den Ressourcen eines Android-Gradle-Projekts angewendet, 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
Laden Sie das Migrationsskript aus dem Tag des ExoPlayer-Projekts auf GitHub herunter, das der Version entspricht, auf die Sie Ihre App aktualisiert haben:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"Machen Sie das Skript ausführbar:
chmod 744 media3-migration.shFühren Sie das Skript mit
--helpaus, um mehr über die Optionen zu erfahren.Führen Sie das Skript mit
-laus, um die für die Migration ausgewählten Dateien aufzulisten. Verwenden Sie-f, um die Auflistung ohne Warnungen zu erzwingen:./media3-migration.sh -l -f /path/to/gradle/project/rootFühre das Script mit
-maus, um Pakete, Klassen und Module Media3 zuzuordnen. Wenn Sie das Script mit der Option-mausführen, werden die Änderungen auf die ausgewählten Dateien angewendet.- Bei Validierungsfehler anhalten, ohne Änderungen vorzunehmen
./media3-migration.sh -m /path/to/gradle/project/root- Erzwungene Ausführung
Wenn das Skript einen Verstoß gegen die Voraussetzungen findet, kann die Migration mit dem Flag
-ferzwungen werden:./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 die folgenden manuellen Schritte aus, nachdem Sie das Skript mit der Option -m ausgeführt haben:
- Prüfen Sie, wie das Skript Ihren Code geändert hat: Verwenden Sie ein Diff-Tool und beheben Sie potenzielle Probleme. Wenn Sie der Meinung sind, dass das Skript ein allgemeines Problem hat, das ohne die Option
-feingeführt wurde, sollten Sie einen Fehler melden. - Projekt erstellen: Verwenden Sie entweder
./gradlew clean buildoder wählen Sie in Android Studio Datei > Projekt mit Gradle-Dateien synchronisieren, dann Build > Projekt bereinigen und dann Build > Projekt neu erstellen aus. Sie können den Build auf dem Tab Build – Build-Ausgabe in Android Studio beobachten.
Empfohlene Folgeschritte:
- Beheben Sie Fehler im Zusammenhang mit der Verwendung instabiler APIs.
- Verworfene API-Aufrufe ersetzen: Verwenden Sie die vorgeschlagene Ersatz-API. Bewegen Sie den Mauszeiger in Android Studio auf die Warnung und sehen Sie sich die JavaDoc des verworfenen Symbols an, um herauszufinden, was Sie stattdessen verwenden sollten.
- Importanweisungen sortieren: Öffnen Sie das Projekt in Android Studio, klicken Sie im Projekt-Viewer mit der rechten Maustaste auf einen Paketordnerknoten und wählen Sie für die Pakete, die die geänderten Quelldateien enthalten, Optimize imports aus.
MediaSessionConnector durch androidx.media3.session.MediaSession ersetzen
In der alten MediaSessionCompat-Welt war der MediaSessionConnector dafür verantwortlich, den Status des Players mit dem Status der Sitzung zu synchronisieren und Befehle von Controllern zu empfangen, die an entsprechende Player-Methoden delegiert werden mussten. Mit AndroidX Media3 wird dies direkt von MediaSession erledigt, ohne dass ein Connector erforderlich ist.
Alle Verweise auf und die Verwendung von MediaSessionConnector entfernen: Wenn Sie das automatisierte Script zum Migrieren von ExoPlayer-Klassen und -Paketen verwendet haben, hat das Script Ihren Code wahrscheinlich in einem nicht kompilierbaren Zustand in Bezug auf die
MediaSessionConnectorhinterlassen, die nicht aufgelöst werden können. Android Studio zeigt Ihnen den fehlerhaften Code an, wenn Sie versuchen, die App zu erstellen oder zu starten.Fügen Sie in der Datei
build.gradle, in der Sie Ihre Abhängigkeiten verwalten, eine Implementierungsabhängigkeit zum AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die alte Abhängigkeit:implementation "androidx.media3:media3-session:1.11.1"Ersetzen Sie
MediaSessionCompatdurchandroidx.media3.session.MediaSession.Verwenden Sie am Code-Standort, an dem Sie die Legacy-
MediaSessionCompaterstellt haben,androidx.media3.session.MediaSession.Builder, um eineMediaSessionzu erstellen. Übergebe den Player, um den Session Builder zu erstellen.Kotlin
val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player).setCallback(MySessionCallback()).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); mediaSession = new MediaSession.Builder(context, player).setCallback(new MySessionCallback()).build();
Implementieren Sie
MySessionCallback, wie es für Ihre App erforderlich ist. Dies ist optional. Wenn du Controllern erlauben möchtest, dem Player Mediendateien hinzuzufügen, implementiereMediaSession.Callback.onAddMediaItems(). Sie stellt verschiedene aktuelle und ältere API-Methoden bereit, mit denen Mediendateien abwärtskompatibel zur Wiedergabe im Player hinzugefügt werden können. Dazu gehören dieMediaController.set/addMediaItems()-Methoden des Media3-Controllers sowie dieTransportControls.prepareFrom*/playFrom*-Methoden der Legacy-API. Eine Beispielimplementierung vononAddMediaItemsfinden Sie in derPlaybackServiceder Session-Demo-App.Gib die Mediensitzung an der Codestelle frei, an der du die Sitzung vor der Migration gelöscht hast:
Kotlin
mediaSession?.run { player.release() release() mediaSession = null }
Java
if (mediaSession != null) { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; }
MediaSessionConnector-Funktionen in Media3
In der folgenden Tabelle sind die Media3 APIs aufgeführt, die Funktionen verarbeiten, die zuvor in MediaSessionConnector implementiert wurden.
| MediaSessionConnector | AndroidX Media3 |
|---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setMediaButtonPreferences() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() wird intern aufgerufen)
|
QueueNavigator |
ForwardingSimpleBasePlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
MediaBrowserService zu MediaLibraryService migrieren
AndroidX Media3 führt MediaLibraryService ein, das MediaBrowserServiceCompat ersetzt. Das JavaDoc von MediaLibraryService und seiner Superklasse MediaSessionService bietet eine gute Einführung in die API und das asynchrone Programmiermodell des Dienstes.
MediaLibraryService ist abwärtskompatibel mit MediaBrowserService. Eine Clientanwendung, die MediaBrowserCompat oder MediaControllerCompat verwendet, funktioniert weiterhin ohne Codeänderungen, wenn eine Verbindung zu einer MediaLibraryService hergestellt wird. Für einen Client ist es transparent, ob Ihre Anwendung einen MediaLibraryService oder einen Legacy-MediaBrowserServiceCompat verwendet.
Damit die Abwärtskompatibilität funktioniert, müssen Sie beide Dienstschnittstellen mit Ihrem Dienst in der
AndroidManifest.xmlregistrieren. So findet ein Client 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>Fügen Sie in der Datei
build.gradle, in der Sie Ihre Abhängigkeiten verwalten, eine Implementierungsabhängigkeit zum AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die Legacy-Abhängigkeit:implementation "androidx.media3:media3-session:1.11.1"Ändern Sie Ihren Dienst so, dass er von einem
MediaLibraryServiceanstelle vonMediaBrowserServiceerbt. Wie bereits erwähnt, istMediaLibraryServicemit dem Legacy-MediaBrowserServicekompatibel. Dementsprechend ist die umfassendere API, die der Dienst den Clients bietet, immer noch dieselbe. Es ist also wahrscheinlich, dass eine App den Großteil der Logik, die für die Implementierung vonMediaBrowserServiceerforderlich ist, beibehalten und für die neueMediaLibraryServiceanpassen kann.Die Hauptunterschiede im Vergleich zur Legacy-
MediaBrowserServiceCompatsind:Methoden für den Dienstlebenszyklus implementieren: Die Methoden, die im Dienst selbst überschrieben werden müssen, sind
onCreateundonDestroy. Hier weist eine App die Bibliothekssitzung, den Player und andere Ressourcen zu oder gibt sie frei. Zusätzlich zu den Standardmethoden für den Dienstlebenszyklus muss eine ApponGetSession(MediaSession.ControllerInfo)überschreiben, um den inonCreateerstelltenMediaLibrarySessionzurückzugeben.MediaLibraryService.MediaLibrarySessionCallback implementieren: Zum Erstellen einer Sitzung ist ein
MediaLibraryService.MediaLibrarySessionCallbackerforderlich, der die eigentlichen Domain-API-Methoden implementiert. Anstatt API-Methoden des Legacy-Dienstes zu überschreiben, überschreiben Sie stattdessen die Methoden vonMediaLibrarySession.Callback.Der Callback wird dann verwendet, um die
MediaLibrarySessionzu erstellen:Kotlin
mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()
Java
mediaLibrarySession = new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();
Die vollständige API des MediaLibrarySessionCallback finden Sie in der API-Dokumentation.
MediaSession.Callback.onAddMediaItems()implementieren: Der CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)dient verschiedenen aktuellen und älteren API-Methoden, die dem Player Medieninhalte für die Wiedergabe auf abwärtskompatible Weise hinzufügen. Dazu gehören dieMediaController.set/addMediaItems()-Methoden des Media3-Controllers sowie dieTransportControls.prepareFrom*/playFrom*-Methoden der Legacy-API. Eine Beispielimplementierung des Callbacks finden Sie in derPlaybackServiceder Session-Demo-App.AndroidX Media3 verwendet
androidx.media3.common.MediaItemanstelle vonMediaBrowserCompat.MediaItemundMediaMetadataCompat. Teile des Codes, die mit den Legacy-Klassen verknüpft sind, müssen entsprechend geändert oder stattdessen dem Media3-MediaItemzugeordnet werden.Das allgemeine asynchrone Programmiermodell wurde in
Futuresgeändert, im Gegensatz zum trennbarenResult-Ansatz vonMediaBrowserServiceCompat. Ihre Dienstimplementierung kann ein asynchronesListenableFuturezurückgeben, anstatt ein Ergebnis zu trennen, oder ein sofortiges Future zurückgeben, um einen Wert direkt zurückzugeben.
PlayerNotificationManager entfernen
Der MediaLibraryService unterstützt Medienbenachrichtigungen automatisch und der PlayerNotificationManager kann entfernt werden, wenn ein MediaLibraryService oder MediaSessionService verwendet wird.
Eine App kann die Benachrichtigung anpassen, indem sie in onCreate() einen benutzerdefinierten MediaNotification.Provider festlegt, der den DefaultMediaNotificationProvider ersetzt. Der MediaLibraryService startet den Dienst dann nach Bedarf im Vordergrund.
Durch das Überschreiben von MediaLibraryService.updateNotification() kann eine App die vollständige Kontrolle über das Posten einer Benachrichtigung und das Starten oder Beenden des Dienstes im Vordergrund übernehmen.
Clientcode mit einem MediaBrowser migrieren
In AndroidX Media3 implementiert ein MediaBrowser die MediaController/Player-Schnittstellen und kann neben dem Durchsuchen der Mediathek auch zur Steuerung der Medienwiedergabe verwendet werden. Wenn Sie in der Legacy-Welt einen MediaBrowserCompat und einen MediaControllerCompat erstellen mussten, können Sie dasselbe tun, indem Sie in Media3 nur den MediaBrowser verwenden.
Ein MediaBrowser kann erstellt werden und auf die Verbindung zum Dienst warten:
Kotlin
scope.launch { val sessionToken = SessionToken(context, ComponentName(context, "MusicService")) browser = MediaBrowser.Builder(context, sessionToken) .setListener(BrowserListener()) .buildAsync() .await() }
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, "MusicService")); ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setListener(new BrowserListener()) .buildAsync();
Unter Wiedergabe in der Mediensitzung steuern erfährst du, wie du einen MediaController zum Steuern der Wiedergabe im Hintergrund erstellst.
Weitere Schritte und Bereinigung
In den folgenden Abschnitten wird erläutert, wie Sie nach Abschluss der ersten Migration mit instabilen API-Lint-Fehlern und verworfenen APIs umgehen.
Fehler aufgrund instabiler API
Nach der Migration zu Media3 werden möglicherweise Lint-Fehler zu instabilen API-Nutzungen angezeigt.
Diese APIs können sicher verwendet werden. Die Lint-Fehler sind ein Nebenprodukt unserer neuen Richtlinie zur Binärkompatibilität. Wenn Sie keine strikte Binärkompatibilität benötigen, können diese Fehler mit einer @OptIn-Annotation ignoriert werden.
Hintergrund
Weder ExoPlayer v1 noch v2 boten eine strikte Binärkompatibilität der Bibliothek zwischen nachfolgenden Versionen. Die ExoPlayer API-Oberfläche ist sehr groß, damit Apps fast jeden Aspekt der Wiedergabe anpassen können. In nachfolgenden Versionen von ExoPlayer wurden gelegentlich Symbolumbenennungen oder andere funktionsgefährdende Änderungen eingeführt (z.B. neue erforderliche Methoden für Schnittstellen). In den meisten Fällen wurden diese Probleme dadurch behoben, dass das neue Symbol eingeführt und das alte Symbol für einige Versionen eingestellt wurde, damit Entwickler Zeit hatten, ihre Verwendungen zu migrieren. Das war jedoch nicht immer möglich.
Diese funktionsgefährdenden Änderungen führten zu zwei Problemen für Nutzer der ExoPlayer-Bibliotheken v1 und v2:
- Ein Upgrade auf die ExoPlayer-Version kann dazu führen, dass Code nicht mehr kompiliert wird.
- Bei einer App, die sowohl direkt als auch über eine Zwischenbibliothek von ExoPlayer abhängig war, musste sichergestellt werden, dass beide Abhängigkeiten dieselbe Version hatten. Andernfalls konnten binäre Inkompatibilitäten zu Abstürzen während der Laufzeit führen.
Verbesserungen in Media3
Media3 bietet Binärkompatibilität für einen Teil der API-Oberfläche. Die Teile, die keine Binärkompatibilität bieten, sind mit @UnstableApi gekennzeichnet.
Um diese Unterscheidung deutlich zu machen, wird bei der Verwendung instabiler API-Symbole ein Lint-Fehler generiert, sofern sie nicht mit @OptIn annotiert sind.
Nach der Migration von ExoPlayer v2 zu Media3 werden möglicherweise viele Lint-Fehler für instabile APIs angezeigt. Dadurch kann der Eindruck entstehen, dass Media3 weniger stabil ist als ExoPlayer v2. Das ist jedoch nicht der Fall. Die „instabilen“ Teile der Media3 API sind genauso stabil wie die gesamte ExoPlayer v2 API-Oberfläche. Die binäre Kompatibilität der stabilen Media3 API-Oberfläche ist in ExoPlayer v2 überhaupt nicht verfügbar. Der Unterschied besteht darin, dass Sie jetzt durch einen Lint-Fehler auf die verschiedenen Stabilitätsstufen aufmerksam gemacht werden.
Fehler bei instabilen API-Lint-Fehlern beheben
Weitere Informationen zum Annotieren von Java- und Kotlin-Nutzungen instabiler APIs mit @OptIn finden Sie im Abschnitt zur Fehlerbehebung bei diesen Lint-Fehlern.
Verworfene APIs
Aufrufe von verworfenen APIs sind in Android Studio möglicherweise durchgestrichen. Wir empfehlen, solche Aufrufe durch die entsprechende Alternative zu ersetzen. Bewegen Sie den Mauszeiger auf das Symbol, um das JavaDoc aufzurufen, in dem die zu verwendende API angegeben ist.
Codebeispiele und Demo-Apps
- AndroidX Media3-Sitzungs-Demo-App (Mobilgeräte und Wear OS)
- Benutzerdefinierte Aktionen
- System-UI-Benachrichtigung, MediaButton/BT
- Wiedergabesteuerung mit Google Assistant
- UAMP: Android Media Player (Zweig media3) (Mobilgeräte, AutomotiveOS)
- System-UI-Benachrichtigung, MediaButton/BT, Fortsetzung der Wiedergabe
- Wiedergabesteuerung über Google Assistant/Wear OS
- AutomotiveOS: benutzerdefinierter Befehl und Anmeldung