Le app che attualmente utilizzano la libreria com.google.android.exoplayer2 autonoma e androidx.media devono eseguire la migrazione a androidx.media3. Utilizza lo script di migrazione per eseguire la migrazione dei file di build Gradle, dei file di codice sorgente Java e Kotlin e dei file di layout XML da ExoPlayer 2.19.1 ad AndroidX Media3 1.1.1.
Panoramica
Prima di eseguire la migrazione, consulta le sezioni seguenti per scoprire di più sui vantaggi delle nuove API, sulle API di cui eseguire la migrazione e sui prerequisiti che il progetto della tua app deve soddisfare.
Perché eseguire la migrazione a Jetpack Media3
- È la nuova casa di ExoPlayer, mentre
com.google.android.exoplayer2non è più disponibile. - Accedi all'API Player tra componenti/processi con
MediaBrowser/MediaController. - Utilizza le funzionalità estese dell'API
MediaSessioneMediaController. - Pubblicizza le funzionalità di riproduzione con il controllo granulare dell'accesso.
- Semplifica la tua app rimuovendo
MediaSessionConnectorePlayerNotificationManager. - Compatibile con le versioni precedenti delle API client media-compat
(
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)
API Media per la migrazione ad AndroidX Media3
- ExoPlayer e le sue estensioni
Sono inclusi tutti i moduli del progetto ExoPlayer precedente, ad eccezione del modulo mediasession, che non è più disponibile. Le app o i moduli che dipendono dai pacchetti incom.google.android.exoplayer2possono essere migrati con lo script di migrazione. - MediaSessionConnector (a seconda dei pacchetti
androidx.media.*diandroidx.media:media:1.4.3+)
RimuoviMediaSessionConnectore utilizzaandroidx.media3.session.MediaSession. - MediaBrowserServiceCompat (a seconda dei pacchetti
androidx.media.*diandroidx.media:media:1.4.3+)
Esegui la migrazione delle sottoclassi diandroidx.media.MediaBrowserServiceCompataandroidx.media3.session.MediaLibraryServicee del codice utilizzandoMediaBrowserCompat.MediaItemaandroidx.media3.common.MediaItem. - MediaBrowserCompat (a seconda dei pacchetti
android.support.v4.media.*diandroidx.media:media:1.4.3+)
Esegui la migrazione del codice client utilizzandoMediaBrowserCompatoMediaControllerCompatper utilizzareandroidx.media3.session.MediaBrowserconandroidx.media3.common.MediaItem.
Prerequisiti
Assicurati che il progetto sia sottoposto al controllo del codice sorgente
Assicurati di poter annullare facilmente le modifiche applicate dagli strumenti di migrazione basati su script. Se non hai ancora il tuo progetto nel controllo del codice sorgente, questo è il momento giusto per iniziare. Se per qualche motivo non vuoi farlo, crea una copia di backup del progetto prima di iniziare la migrazione.
Aggiornare la tua app
Ti consigliamo di aggiornare il progetto per utilizzare la versione più recente della libreria ExoPlayer e rimuovere tutte le chiamate ai metodi ritirati. Se intendi utilizzare lo script per la migrazione, devi far corrispondere la versione a cui stai eseguendo l'aggiornamento con quella gestita dallo script.
Aumenta il valore compileSdkVersion della tua app ad almeno 32.
Esegui l'upgrade di Gradle e del plug-in Android Studio per Gradle a una versione recente che funzioni con le dipendenze aggiornate riportate sopra. Ad esempio:
- Versione del plug-in Android per Gradle: 7.1.0
- Versione Gradle: 7.4
Sostituisci tutte le istruzioni di importazione con caratteri jolly che utilizzano un asterisco (*) e utilizza istruzioni di importazione con nome completo: elimina le istruzioni di importazione con caratteri jolly e utilizza Android Studio per importare le istruzioni con nome completo (F2 - Alt/Invio, F2 - Alt/Invio…).
Esegui la migrazione da
com.google.android.exoplayer2.PlayerViewacom.google.android.exoplayer2.StyledPlayerView. Questo è necessario perché non esiste un equivalente dicom.google.android.exoplayer2.PlayerViewin AndroidX Media3.
Esegui la migrazione di ExoPlayer con il supporto degli script
Lo script facilita il passaggio da com.google.android.exoplayer2 alla nuova struttura di pacchetti e moduli in androidx.media3. Lo script applica alcuni controlli di convalida al progetto e stampa avvisi se la convalida non va a buon fine.
In caso contrario, applica le mappature di classi e pacchetti rinominati nelle risorse di un progetto Gradle Android scritto in Java o 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
Utilizzo dello script di migrazione
Scarica lo script di migrazione dal tag del progetto ExoPlayer su GitHub corrispondente alla versione a cui hai aggiornato l'app:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"Rendi eseguibile lo script:
chmod 744 media3-migration.shEsegui lo script con
--helpper scoprire le opzioni.Esegui lo script con
-lper elencare l'insieme di file selezionati per la migrazione (utilizza-fper forzare l'elenco senza avvisi):./media3-migration.sh -l -f /path/to/gradle/project/rootEsegui lo script con
-mper mappare pacchetti, classi e moduli a Media3. L'esecuzione dello script con l'opzione-mapplicherà le modifiche ai file selezionati.- Interrompi in caso di errore di convalida senza apportare modifiche
./media3-migration.sh -m /path/to/gradle/project/root- Esecuzione forzata
Se lo script rileva una violazione dei prerequisiti, la migrazione può essere forzata con il 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
Completa questi passaggi manuali dopo aver eseguito lo script con l'opzione -m:
- Controlla in che modo lo script ha modificato il codice: utilizza uno strumento di diff e risolvi i potenziali problemi (valuta la possibilità di segnalare un bug se ritieni che lo script abbia un problema generale introdotto senza passare l'opzione
-f). - Crea il progetto: utilizza
./gradlew clean buildo in Android Studio scegli File > Sincronizza progetto con i file Gradle, poi Crea > Pulisci progetto e infine Crea > Ricrea progetto (monitora la build nella scheda "Build - Build Output" di Android Studio).
Passaggi successivi consigliati:
- Risolvi l'attivazione degli errori relativi all'utilizzo di API instabili.
- Sostituisci le chiamate API deprecate: utilizza l'API sostitutiva suggerita. Tieni il puntatore sopra l'avviso in Android Studio e consulta il JavaDoc del simbolo deprecato per scoprire cosa utilizzare al posto di una determinata chiamata.
- Ordina le istruzioni di importazione: apri il progetto in Android Studio, quindi fai clic con il tasto destro del mouse su un nodo della cartella del pacchetto nel visualizzatore del progetto e scegli Ottimizza importazioni sui pacchetti che contengono i file di origine modificati.
Sostituisci MediaSessionConnector con androidx.media3.session.MediaSession
Nel mondo precedente di MediaSessionCompat, MediaSessionConnector era responsabile della sincronizzazione dello stato del player con lo stato della sessione e della ricezione dei comandi dai controller che richiedevano la delega ai metodi del player appropriati. Con AndroidX Media3, questa operazione viene eseguita direttamente da MediaSession senza richiedere un connettore.
Rimuovi tutti i riferimenti e l'utilizzo di MediaSessionConnector:se hai utilizzato lo script automatico per eseguire la migrazione di classi e pacchetti ExoPlayer, è probabile che lo script abbia lasciato il codice in uno stato non compilabile per quanto riguarda
MediaSessionConnector, che non può essere risolto. Android Studio ti mostrerà il codice non funzionante quando provi a creare o avviare l'app.Nel file
build.gradlein cui gestisci le dipendenze, aggiungi una dipendenza di implementazione al modulo della sessione AndroidX Media3 e rimuovi la dipendenza precedente:implementation "androidx.media3:media3-session:1.11.1"Sostituisci
MediaSessionCompatconandroidx.media3.session.MediaSession.Nel sito del codice in cui hai creato la risorsa
MediaSessionCompatlegacy, utilizzaandroidx.media3.session.MediaSession.Builderper creare unaMediaSession. Passa il player per creare il generatore di sessioni.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();
Implementa
MySessionCallbackcome richiesto dalla tua app. Questa opzione è facoltativa. Se vuoi consentire ai controller di aggiungere elementi multimediali al player, implementaMediaSession.Callback.onAddMediaItems(). Fornisce vari metodi API attuali e legacy che aggiungono elementi multimediali al player per la riproduzione in modo compatibile con le versioni precedenti. Sono inclusi i metodiMediaController.set/addMediaItems()del controller Media3 e i metodiTransportControls.prepareFrom*/playFrom*dell'API precedente. Un'implementazione di esempio dionAddMediaItemsè disponibile inPlaybackServicedell'app demo della sessione.Rilascia la sessione multimediale nel punto del codice in cui hai eliminato la sessione prima della migrazione:
Kotlin
mediaSession?.run { player.release() release() mediaSession = null }
Java
if (mediaSession != null) { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; }
Funzionalità MediaSessionConnector in Media3
La tabella seguente mostra le API Media3 che gestiscono le funzionalità precedentemente implementate in MediaSessionConnector.
| MediaSessionConnector | AndroidX Media3 |
|---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setMediaButtonPreferences() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() viene chiamato internamente)
|
QueueNavigator |
ForwardingSimpleBasePlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Esegui la migrazione di MediaBrowserService a MediaLibraryService
AndroidX Media3 introduce MediaLibraryService, che sostituisce
MediaBrowserServiceCompat. Il JavaDoc di MediaLibraryService e della sua superclasse MediaSessionService fornisce una buona introduzione all'API e al modello di programmazione asincrona del servizio.
MediaLibraryService è compatibile con le versioni precedenti di
MediaBrowserService. Un'app client che utilizza MediaBrowserCompat o MediaControllerCompat continua a funzionare senza modifiche al codice quando si connette a MediaLibraryService. Per un client, è trasparente se la tua app utilizza un MediaLibraryService o un MediaBrowserServiceCompat legacy.
Affinché la compatibilità con le versioni precedenti funzioni, devi registrare entrambe le interfacce di servizio con il tuo servizio in
AndroidManifest.xml. In questo modo, un client trova il tuo servizio tramite l'interfaccia di servizio richiesta:<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>Nel file
build.gradlein cui gestisci le dipendenze, aggiungi una dipendenza di implementazione al modulo di sessione AndroidX Media3 e rimuovi la dipendenza precedente:implementation "androidx.media3:media3-session:1.11.1"Modifica il servizio in modo che erediti da un
MediaLibraryServiceanziché daMediaBrowserServiceCome accennato in precedenza,MediaLibraryServiceè compatibile con il servizio legacyMediaBrowserService. Di conseguenza, l'API più ampia che il servizio offre ai client è ancora la stessa. Pertanto, è probabile che un'app possa mantenere la maggior parte della logica richiesta per implementareMediaBrowserServicee adattarla al nuovoMediaLibraryService.Le principali differenze rispetto alla versione precedente di
MediaBrowserServiceCompatsono le seguenti:Implementa i metodi del ciclo di vita del servizio:i metodi di cui è necessario eseguire l'override sul servizio stesso sono
onCreate/onDestroy, in cui un'app alloca/rilascia la sessione della libreria, il player e altre risorse. Oltre ai metodi standard del ciclo di vita del servizio, un'app deve eseguire l'override dionGetSession(MediaSession.ControllerInfo)per restituire l'oggettoMediaLibrarySessioncreato inonCreate.Implementa MediaLibraryService.MediaLibrarySessionCallback: la creazione di una sessione richiede un
MediaLibraryService.MediaLibrarySessionCallbackche implementi i metodi dell'API del dominio effettivo. Quindi, anziché eseguire l'override dei metodi API del servizio legacy, eseguirai l'override dei metodi diMediaLibrarySession.Callback.Il callback viene quindi utilizzato per creare
MediaLibrarySession:Kotlin
mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()
Java
mediaLibrarySession = new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();
Trova l'API completa di MediaLibrarySessionCallback nella documentazione dell'API.
Implementa
MediaSession.Callback.onAddMediaItems(): il callbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)gestisce vari metodi API attuali e legacy che aggiungono elementi multimediali al player per la riproduzione in modo compatibile con le versioni precedenti. Sono inclusi i metodiMediaController.set/addMediaItems()del controller Media3 e i metodiTransportControls.prepareFrom*/playFrom*dell'API precedente. Un'implementazione di esempio del callback è disponibile nelPlaybackServicedell'app demo della sessione.AndroidX Media3 utilizza
androidx.media3.common.MediaItemanziché MediaBrowserCompat.MediaItem e MediaMetadataCompat. Le parti del codice collegate alle classi legacy devono essere modificate di conseguenza o mappate aMediaItemdi Media3.Il modello di programmazione asincrona generale è cambiato in
Futures, a differenza dell'approccioResultscollegabile diMediaBrowserServiceCompat. L'implementazione del servizio può restituire unListenableFutureasincrono anziché scollegare un risultato o restituire un Future immediato per restituire direttamente un valore.
Rimuovi PlayerNotificationManager
MediaLibraryService supporta automaticamente le notifiche multimediali e
PlayerNotificationManager può essere rimosso quando si utilizza MediaLibraryService o
MediaSessionService.
Un'app può personalizzare la notifica impostando un MediaNotification.Provider personalizzato in onCreate() che sostituisce DefaultMediaNotificationProvider. MediaLibraryService si occupa quindi di avviare il servizio in primo piano, come richiesto.
Eseguendo l'override di MediaLibraryService.updateNotification(), un'app può assumere la piena proprietà della pubblicazione di una notifica e dell'avvio/arresto del servizio in primo piano, se necessario.
Esegui la migrazione del codice client utilizzando un MediaBrowser
Con AndroidX Media3, un MediaBrowser implementa le interfacce MediaController/Player e può essere utilizzato per controllare la riproduzione dei contenuti multimediali, oltre che per sfogliare la raccolta multimediale. Se nel mondo legacy dovevi creare un MediaBrowserCompat e un MediaControllerCompat, puoi fare lo stesso utilizzando solo MediaBrowser in Media3.
È possibile creare un MediaBrowser e attendere che venga stabilita la connessione al servizio:
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();
Consulta la sezione
Controlla la riproduzione nella sessione multimediale
per scoprire come creare un MediaController per controllare la riproduzione in
background.
Passaggi successivi e pulizia
Errori relativi all'API instabile
Dopo la migrazione a Media3, potresti visualizzare errori di lint relativi a utilizzi di API instabili.
Queste API sono sicure da usare e gli errori di lint sono un effetto collaterale delle nostre nuove garanzie di compatibilità binaria. Se non hai bisogno di una compatibilità binaria rigorosa, questi errori possono essere eliminati in sicurezza con un'annotazione @OptIn.
Sfondo
Né ExoPlayer v1 né v2 fornivano garanzie rigorose sulla compatibilità binaria della libreria tra le versioni successive. La superficie dell'API ExoPlayer è molto ampia per progettazione, in modo da consentire alle app di personalizzare quasi ogni aspetto della riproduzione. Le versioni successive di ExoPlayer introducevano occasionalmente ridenominazioni dei simboli o altre modifiche che provocano un errore (ad es. nuovi metodi obbligatori sulle interfacce). Nella maggior parte dei casi, queste interruzioni sono state mitigate introducendo il nuovo simbolo e ritirando quello precedente per alcune versioni, in modo da dare agli sviluppatori il tempo di eseguire la migrazione dei loro utilizzi, ma non è stato sempre possibile.
Queste modifiche che provocano un errore hanno causato due problemi agli utenti delle librerie ExoPlayer v1 e v2:
- Un upgrade alla versione di ExoPlayer potrebbe causare l'interruzione della compilazione del codice.
- Un'app che dipendeva da ExoPlayer sia direttamente sia tramite una libreria intermedia doveva garantire che entrambe le dipendenze fossero della stessa versione, altrimenti le incompatibilità binarie potevano causare arresti anomali in fase di esecuzione.
Miglioramenti in Media3
Media3 garantisce la compatibilità binaria per un sottoinsieme della superficie dell'API. Le parti che non garantiscono la compatibilità binaria sono contrassegnate con @UnstableApi. Per chiarire questa distinzione, gli utilizzi di simboli API instabili generano un errore lint, a meno che non siano annotati con @OptIn.
Dopo la migrazione da ExoPlayer v2 a Media3, potresti visualizzare molti errori di lint dell'API instabile. Questo potrebbe far sembrare Media3 "meno stabile" di ExoPlayer v2. Non è così. Le parti "instabili" dell'API Media3 hanno lo stesso livello di stabilità dell'intera superficie dell'API ExoPlayer v2 e le garanzie della superficie dell'API Media3 stabile non sono affatto disponibili in ExoPlayer v2. La differenza è semplicemente che un errore di lint ora ti avvisa dei diversi livelli di stabilità.
Gestisci gli errori di linting dell'API instabile
Per informazioni dettagliate su come annotare gli utilizzi Java e Kotlin di API instabili con @OptIn, consulta la sezione sulla risoluzione dei problemi relativi a questi errori di lint.
API deprecate
Potresti notare che le chiamate alle API deprecate sono barrate in Android Studio. Ti consigliamo di sostituire queste chiamate con l'alternativa appropriata. Passa il mouse sopra il simbolo per visualizzare il JavaDoc che indica quale API utilizzare.
Esempi di codice e app demo
- App demo della sessione AndroidX Media3 (dispositivi mobili e Wear OS)
- Azioni personalizzate
- Notifica della UI di sistema, MediaButton/BT
- Controllo della riproduzione con l'Assistente Google
- UAMP: Android Media Player (branch media3) (dispositivi mobili, AutomotiveOS)
- Notifica della UI di sistema, MediaButton/BT, ripresa della riproduzione
- Controllo della riproduzione con l'Assistente Google/Wear OS
- AutomotiveOS: comando personalizzato e accesso