AndroidX Media3 taşıma kılavuzu

Şu anda bağımsız com.google.android.exoplayer2 kitaplığını ve androidx.media kullanan uygulamalar androidx.media3'a taşınmalıdır. Gradle derleme dosyalarını, Java ve Kotlin kaynak dosyalarını ve XML düzen dosyalarını ExoPlayer 2.19.1'dan AndroidX Media3 1.1.1'e taşımak için taşıma komut dosyasını kullanın.

Genel Bakış

Taşıma işleminden önce aşağıdaki bölümleri inceleyerek yeni API'lerin avantajları, taşınacak API'ler ve uygulamanızın projesinin karşılaması gereken ön koşullar hakkında daha fazla bilgi edinin.

Neden Jetpack Media3'e geçmelisiniz?

  • ExoPlayer'ın yeni adresi olan com.google.android.exoplayer2 ise kullanımdan kaldırıldı.
  • MediaBrowser/MediaController ile bileşenler/işlemler arasında Player API'ye erişin.
  • MediaSession ve MediaController API'nin genişletilmiş özelliklerini kullanın.
  • Ayrıntılı erişim denetimi ile oynatma özelliklerinin reklamını yapın.
  • MediaSessionConnector ve PlayerNotificationManager öğelerini kaldırarak uygulamanızı basitleştirin.
  • Medya uyumluluğu istemci API'leriyle geriye dönük uyumludur. (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

AndroidX Media3'e taşınacak medya API'leri

  • ExoPlayer ve uzantıları
    Bu, kullanımdan kaldırılan mediasession modülü hariç olmak üzere eski ExoPlayer projesinin tüm modüllerini içerir. com.google.android.exoplayer2 içindeki paketlere bağlı uygulamalar veya modüller, taşıma komut dosyasıyla taşınabilir.
  • MediaSessionConnector (androidx.media:media:1.4.3+ paketlerine bağlı olarak)
    MediaSessionConnector öğesini kaldırın ve bunun yerine androidx.media3.session.MediaSession öğesini kullanın.androidx.media.*
  • MediaBrowserServiceCompat (androidx.media:media:1.4.3+'ın androidx.media.* paketlerine bağlı olarak)
    androidx.media.MediaBrowserServiceCompat alt sınıflarını androidx.media3.session.MediaLibraryService'ye ve MediaBrowserCompat.MediaItem kullanılarak yazılan kodları androidx.media3.common.MediaItem'ye taşıyın.
  • MediaBrowserCompat (androidx.media:media:1.4.3+ paketlerine bağlı olarak)
    MediaBrowserCompat veya MediaControllerCompat kullanarak istemci kodunu androidx.media3.session.MediaBrowser ile androidx.media3.common.MediaItem kullanacak şekilde taşıyın.android.support.v4.media.*

Ön koşullar

  1. Projenizin kaynak kontrolü altında olduğundan emin olun

    Komut dosyası içeren taşıma araçları tarafından uygulanan değişiklikleri kolayca geri alabileceğinizden emin olun. Projenizi henüz kaynak kontrolü altına almadıysanız şimdi bu işe başlamak için iyi bir zaman. Bunu yapmak istemiyorsanız taşıma işlemine başlamadan önce projenizin yedek kopyasını oluşturun.

  2. Uygulamanızı güncelleme

    • Projenizi, ExoPlayer kitaplığının en son sürümünü kullanacak şekilde güncellemenizi ve desteği sonlandırılan yöntemlere yapılan tüm çağrıları kaldırmanızı öneririz. Taşıma için komut dosyasını kullanmayı planlıyorsanız güncellediğiniz sürümü komut dosyasının işlediği sürümle eşleştirmeniz gerekir.

    • Uygulamanızın compileSdkVersion'ını en az 32'ye yükseltin.

    • Gradle'ı ve Android Studio Gradle eklentisini yukarıdaki güncellenmiş bağımlılıklarla çalışan yeni bir sürüme yükseltin. Örneğin:

      • Android Gradle eklentisi sürümü: 7.1.0
      • Gradle sürümü: 7.4
    • Yıldız işareti (*) kullanan tüm joker karakterli içe aktarma ifadelerini değiştirin ve tam nitelikli içe aktarma ifadelerini kullanın: Joker karakterli içe aktarma ifadelerini silin ve tam nitelikli ifadeleri içe aktarmak için Android Studio'yu kullanın (F2 - Alt/Enter, F2 - Alt/Enter, ...).

    • com.google.android.exoplayer2.PlayerView'ten com.google.android.exoplayer2.StyledPlayerView'e taşıma AndroidX Media3'te com.google.android.exoplayer2.PlayerView'e eşdeğer bir işlev olmadığından bu gereklidir.

ExoPlayer'ı komut dosyası desteğiyle taşıma

Bu komut dosyası, com.google.android.exoplayer2'dan androidx.media3 altındaki yeni paket ve modül yapısına geçişi kolaylaştırır. Komut dosyası, projenizde bazı doğrulama kontrolleri uygular ve doğrulama başarısız olursa uyarılar yazdırır. Aksi takdirde, Java veya Kotlin ile yazılmış bir Android Gradle projesinin kaynaklarında yeniden adlandırılan sınıfların ve paketlerin eşlemelerini uygular.

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

Taşıma komut dosyasını kullanma

  1. Uygulamanızı güncellediğiniz sürüme karşılık gelen GitHub'daki ExoPlayer projesinin etiketinden taşıma komut dosyasını indirin:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. Komut dosyasını yürütülebilir hale getirin:

    chmod 744 media3-migration.sh
    
  3. Seçenekler hakkında bilgi edinmek için --help ile komut dosyasını çalıştırın.

  4. -l ile komut dosyasını çalıştırarak taşınmak üzere seçilen dosyaları listeleyin (uyarı olmadan listelemeyi zorlamak için -f kullanın):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. Paketleri, sınıfları ve modülleri Media3'e eşlemek için -m ile komut dosyasını çalıştırın. Komut dosyasını -m seçeneğiyle çalıştırmak, seçili dosyalarda değişiklik yapılmasını sağlar.

    • Değişiklik yapmadan doğrulama hatasında durdurma
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • Zorunlu yürütme

    Komut dosyası ön koşulların ihlal edildiğini tespit ederse taşıma işlemi -f işaretiyle zorlanabilir:

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

Komut dosyasını -m seçeneğiyle çalıştırdıktan sonra aşağıdaki manuel adımları tamamlayın:

  1. Komut dosyasının kodunuzu nasıl değiştirdiğini kontrol edin: Bir farklılık aracı kullanın ve olası sorunları düzeltin (Komut dosyasının, -f seçeneği iletilmeden genel bir sorun oluşturduğunu düşünüyorsanız hata kaydı gönderebilirsiniz).
  2. Projeyi oluşturun: ./gradlew clean build kullanın veya Android Studio'da File > Sync Project with Gradle Files'ı (Dosya > Projeyi Gradle Dosyalarıyla Senkronize Et) seçin, ardından Build > Clean project'i (Derleme > Projeyi Temizle) ve Build > Rebuild project'i (Derleme > Projeyi Yeniden Oluştur) seçin (Android Studio'nun "Build - Build Output" sekmesinde derlemenizi izleyin).

Önerilen takip adımları:

  1. Kararsız API'lerin kullanımıyla ilgili hatalar için etkinleştirme sorununu çözün.
  2. Desteği sonlandırılan API çağrılarını değiştirin: Önerilen yedek API'yi kullanın. Android Studio'da imleci uyarının üzerine getirin ve belirli bir çağrı yerine ne kullanacağınızı öğrenmek için JavaDoc'taki desteği sonlandırılan sembole bakın.
  3. İçe aktarma ifadelerini sıralama: Projeyi Android Studio'da açın, ardından proje görüntüleyicide bir paket klasörü düğümünü sağ tıklayın ve değiştirilen kaynak dosyaları içeren paketlerde İçe aktarmaları optimize et'i seçin.

MediaSessionConnector yerine androidx.media3.session.MediaSession koyun

Eski MediaSessionCompat dünyasında, MediaSessionConnector, oynatıcının durumunu oturumun durumuyla senkronize etmekten ve uygun oynatıcı yöntemlerine temsil edilmesi gereken kontrol cihazlarından gelen komutları almaktan sorumluydu. AndroidX Media3'te bu işlem, bağlayıcı gerektirmeden doğrudan MediaSession tarafından yapılır.

  1. MediaSessionConnector'ın tüm referanslarını ve kullanımını kaldırın: ExoPlayer sınıflarını ve paketlerini taşımak için otomatik komut dosyasını kullandıysanız komut dosyası, kodunuzu MediaSessionConnector ile ilgili olarak derlenemez durumda bırakmış olabilir. Android Studio, uygulamayı oluşturmaya veya başlatmaya çalıştığınızda bozuk kodu gösterir.

  2. Bağımlılıklarınızı yönettiğiniz build.gradle dosyasına AndroidX Media3 oturum modülüne bir uygulama bağımlılığı ekleyin ve eski bağımlılığı kaldırın:

    implementation "androidx.media3:media3-session:1.7.1"
    
  3. MediaSessionCompat yerine androidx.media3.session.MediaSession koyun.

  4. Eski MediaSessionCompat öğesini oluşturduğunuz kod sitesinde MediaSession androidx.media3.session.MediaSession.Builder oluşturmak için androidx.media3.session.MediaSession.Builder öğesini kullanın. Oturum oluşturucuyu oluşturmak için oyuncuya pas verin.

    val player = ExoPlayer.Builder(context).build()
    mediaSession = MediaSession.Builder(context, player)
        .setSessionCallback(MySessionCallback())
        .build()
    
  5. MySessionCallback'ı uygulamanızın gerektirdiği şekilde uygulayın. Bu adım isteğe bağlıdır. Denetleyicilerin oynatıcıya medya öğeleri eklemesine izin vermek istiyorsanız MediaSession.Callback.onAddMediaItems()'yi uygulayın. Geriye dönük uyumlu bir şekilde oynatmak için oynatıcıya medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemleri sunar. Bu, Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemlerinin yanı sıra eski API'nin TransportControls.prepareFrom*/playFrom* yöntemlerini de içerir. onAddMediaItems için örnek bir uygulama, oturum demo uygulamasının PlaybackService bölümünde bulunabilir.

  6. Taşımadan önce oturumunuzu sonlandırdığınız kod sitesinde medya oturumunu serbest bırakın:

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

Media3'teki MediaSessionConnector işlevi

Aşağıdaki tabloda, daha önce MediaSessionConnector'da uygulanan işlevleri işleyen Media3 API'leri gösterilmektedir.

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setMediaButtonPreferences()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() dahili olarak adlandırılır)
QueueNavigator ForwardingSimpleBasePlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

MediaBrowserService alanını MediaLibraryService alanına taşıma

AndroidX Media3, MediaBrowserServiceCompat yerine kullanılan MediaLibraryService öğesini sunar. MediaLibraryService ve üst sınıfı MediaSessionService JavaDoc'u, API'ye ve hizmetin eşzamansız programlama modeline iyi bir giriş sağlar.

MediaLibraryService, MediaBrowserService ile geriye dönük uyumludur. MediaBrowserCompat veya MediaControllerCompat kullanan bir istemci uygulaması, MediaLibraryService öğesine bağlanırken kod değişikliği olmadan çalışmaya devam eder. İstemciler, uygulamanızın MediaLibraryService veya eski bir MediaBrowserServiceCompat kullandığını şeffaf bir şekilde görebilir.

Hizmet, etkinlik ve harici uygulamaları içeren uygulama bileşeni şeması.
Şekil 1: Medya uygulaması bileşenine genel bakış
  1. Geriye dönük uyumluluğun çalışması için AndroidManifest.xml içinde her iki hizmet arayüzünü de hizmetinize kaydetmeniz gerekir. Bu şekilde, bir istemci hizmetinizi gerekli hizmet arayüzüyle bulur:

    <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. Bağımlılıklarınızı yönettiğiniz build.gradle dosyasına AndroidX Media3 oturum modülüne bir uygulama bağımlılığı ekleyin ve eski bağımlılığı kaldırın:

    implementation "androidx.media3:media3-session:1.7.1"
    
  3. Hizmetinizi MediaBrowserService yerine MediaLibraryService öğesinden devralacak şekilde değiştirin. MediaBrowserService Daha önce de belirtildiği gibi MediaLibraryService, eski MediaBrowserService ile uyumludur. Dolayısıyla, hizmetin istemcilere sunduğu daha geniş kapsamlı API aynı kalır. Bu nedenle, bir uygulamanın MediaBrowserService'ı uygulamak için gereken mantığın çoğunu koruyup yeni MediaLibraryService'a uyarlaması olasıdır.

    Eski sürüme kıyasla temel farklar şunlardır: MediaBrowserServiceCompat

    • Hizmet yaşam döngüsü yöntemlerini uygulayın: Hizmetin kendisinde geçersiz kılınması gereken yöntemler onCreate/onDestroy'dir. Burada bir uygulama, kitaplık oturumunu, oynatıcıyı ve diğer kaynakları ayırır/serbest bırakır. Standart hizmet yaşam döngüsü yöntemlerine ek olarak, bir uygulamanın onGetSession(MediaSession.ControllerInfo) yöntemini geçersiz kılıp onCreate içinde oluşturulan MediaLibrarySession değerini döndürmesi gerekir.

    • MediaLibraryService.MediaLibrarySessionCallback'i uygulayın: Bir oturum oluşturmak için gerçek alan API'si yöntemlerini uygulayan bir MediaLibraryService.MediaLibrarySessionCallback gerekir. Bu nedenle, eski hizmetin API yöntemlerini geçersiz kılmak yerine MediaLibrarySession.Callback yöntemlerini geçersiz kılacaksınız.

      Geri arama daha sonra MediaLibrarySession oluşturmak için kullanılır:

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

      API belgelerinde MediaLibrarySessionCallback'in tam API'sini bulun.

    • MediaSession.Callback.onAddMediaItems() uygulayınonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>): Geri çağırma, geriye dönük uyumlu şekilde oynatmak için oynatıcıya medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemlerine hizmet eder. Buna, Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemlerinin yanı sıra eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri de dahildir. Geri arama işlevinin örnek bir uygulamasına oturum demo uygulamasının PlaybackService bölümünden ulaşabilirsiniz.

    • AndroidX Media3, MediaBrowserCompat.MediaItem ve MediaMetadataCompat yerine androidx.media3.common.MediaItem kullanıyor. Eski sınıflarla ilişkili kodunuzun bölümlerinin buna göre değiştirilmesi veya Media3 MediaItem ile eşlenmesi gerekir.

    • Genel asenkron programlama modeli, MediaBrowserServiceCompat'in ayrılabilir Result yaklaşımının aksine Futures olarak değiştirildi. Hizmet uygulamanız, sonucu ayırmak yerine eşzamansız bir ListenableFuture döndürebilir veya değeri doğrudan döndürmek için anında bir Future döndürebilir.

Remove PlayerNotificationManager

MediaLibraryService, medya bildirimlerini otomatik olarak destekler ve MediaLibraryService ya da MediaSessionService kullanılırken PlayerNotificationManager kaldırılabilir.

Bir uygulama, onCreate() içinde DefaultMediaNotificationProvider yerine özel bir MediaNotification.Provider ayarlayarak bildirimi özelleştirebilir. MediaLibraryService, hizmeti gerektiği gibi ön planda başlatır.

MediaLibraryService.updateNotification() geçersiz kılınarak uygulama, bildirim yayınlama ve hizmeti gerektiği gibi ön planda başlatma/durdurma konusunda tam kontrol sahibi olabilir.

MediaBrowser kullanarak istemci kodunu taşıma

AndroidX Media3 ile MediaBrowser, MediaController/Player arayüzlerini uygular ve medya kitaplığına göz atmanın yanı sıra medya oynatmayı kontrol etmek için kullanılabilir. Eski sistemde MediaBrowserCompat ve MediaControllerCompat oluşturmanız gerekiyorsa Media3'te yalnızca MediaBrowser kullanarak aynı işlemi yapabilirsiniz.

Bir MediaBrowser oluşturulabilir ve hizmetle bağlantının kurulması beklenebilir:

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

Arka planda oynatmayı kontrol etmek için MediaController oluşturmayı öğrenmek üzere Medya oturumunda oynatmayı kontrol etme bölümüne göz atın.

Diğer adımlar ve temizleme

Kararsız API hataları

Media3'e geçiş yaptıktan sonra, kararsız API kullanımlarıyla ilgili lint hataları görebilirsiniz. Bu API'ler güvenle kullanılabilir ve lint hataları, yeni ikili uyumluluk garantilerimizin bir yan ürünüdür. Katı ikili uyumluluk gerekmiyorsa bu hatalar @OptIn ek açıklamasıyla güvenli bir şekilde bastırılabilir.

Arka plan

Ne ExoPlayer v1 ne de v2, kitaplığın sonraki sürümler arasında ikili uyumluluğu konusunda kesin garantiler vermiyordu. ExoPlayer API yüzeyi, uygulamaların oynatmanın neredeyse her yönünü özelleştirmesine olanak tanımak için tasarım gereği çok büyüktür. ExoPlayer'ın sonraki sürümlerinde zaman zaman sembol yeniden adlandırmaları veya diğer önemli değişiklikler (ör. arayüzlerdeki yeni zorunlu yöntemler) yapılıyordu. Çoğu durumda, geliştiricilerin kullanımlarını taşımasına zaman tanımak için birkaç sürüm boyunca eski sembolün desteği sonlandırılırken yeni sembolün kullanıma sunulmasıyla bu bozulmalar azaltıldı ancak bu her zaman mümkün olmadı.

Bu önemli değişiklikler, ExoPlayer v1 ve v2 kitaplıklarının kullanıcıları için iki soruna neden oldu:

  1. ExoPlayer sürümüne yükseltme, kodun derlenmesinin durmasına neden olabilir.
  2. Hem doğrudan hem de ara bir kitaplık aracılığıyla ExoPlayer'a bağımlı olan bir uygulamanın, her iki bağımlılığın da aynı sürümde olmasını sağlaması gerekiyordu. Aksi takdirde, ikili uyumsuzluklar çalışma zamanında çökmelere neden olabilirdi.

Media3'teki iyileştirmeler

Media3, API yüzeyinin bir alt kümesi için ikili uyumluluğu garanti eder. İkili uyumluluğu garanti etmeyen kısımlar @UnstableApi ile işaretlenir. Bu ayrımı netleştirmek için, kararsız API sembollerinin kullanımları @OptIn ile açıklama eklenmediği sürece lint hatası oluşturur.

ExoPlayer v2'den Media3'e geçiş yaptıktan sonra çok sayıda kararsız API lint hatası görebilirsiniz. Bu durum, Media3'ün ExoPlayer v2'den "daha az kararlı" olduğu izlenimini yaratabilir. Buna gerek yoktur. Media3 API'nin "kararsız" kısımları, ExoPlayer v2 API yüzeyinin tamamı ile aynı kararlılık düzeyine sahiptir ve kararlı Media3 API yüzeyinin garantileri ExoPlayer v2'de hiç kullanılamaz. Aradaki fark, lint hatasının artık farklı kararlılık düzeyleri konusunda sizi uyarmasıdır.

Kararsız API lint hatalarını giderme

Java ve Kotlin'de kararsız API kullanımlarını @OptIn ile açıklama ekleme hakkında ayrıntılı bilgi için bu lint hatalarıyla ilgili sorun giderme bölümüne bakın.

Kullanımdan kaldırılan API'ler

Desteği sonlandırılan API'lere yapılan çağrıların Android Studio'da üstü çizili olduğunu görebilirsiniz. Bu tür çağrıları uygun alternatiflerle değiştirmenizi öneririz. Hangi API'nin kullanılacağını belirten JavaDoc'u görmek için sembolün üzerine gelin.

Ekran görüntüsü: JavaDoc&#39;u, kullanımdan kaldırılmış yöntemin alternatifiyle görüntüleme
Şekil 3: Android Studio'daki JavaDoc ipucu, kullanımdan kaldırılan tüm semboller için alternatif önerir.

Kod örnekleri ve demo uygulamaları