AndroidX Media3 taşıma kılavuzu

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

Genel Bakış

Taşıma işleminden önce yeni API'lerin avantajları, taşınacak API'ler ve uygulama projenizin karşılaması gereken ön koşullar hakkında daha fazla bilgi edinmek için aşağıdaki bölümleri inceleyin.

Neden Jetpack Media3'e geçmelisiniz?

  • com.google.android.exoplayer2 kullanımdan kaldırılırken ExoPlayer'ın yeni evi budur.
  • MediaBrowser/MediaController ile bileşenler/işlemler genelinde 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 uyumlu istemci API'leriyle geriye dönük uyumlu (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

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

  • ExoPlayer ve uzantıları
    Buna, kullanımdan kaldırılan mediasession modülü hariç eski ExoPlayer projesinin tüm modülleri dahildir. 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+'in androidx.media.* paketlerine bağlı olarak)
    MediaSessionConnector öğesini kaldırın ve bunun yerine androidx.media3.session.MediaSession öğesini kullanın.
  • MediaBrowserServiceCompat (androidx.media:media:1.4.3+'in androidx.media.* paketlerine bağlı olarak)
    androidx.media.MediaBrowserServiceCompat alt sınıflarını androidx.media3.session.MediaLibraryService'ye, MediaBrowserCompat.MediaItem kullanan kodu ise androidx.media3.common.MediaItem'e taşıyın.
  • MediaBrowserCompat (androidx.media:media:1.4.3+'in android.support.v4.media.* paketlerine bağlı olarak)
    androidx.media3.common.MediaItem ile androidx.media3.session.MediaBrowser'ı kullanmak için MediaBrowserCompat'i veya MediaControllerCompat'i kullanarak istemci kodunu taşıyın.

Ön koşullar

  1. Projenizin kaynak kontrolünde olduğundan emin olun

    Komut dosyası taşıma araçları tarafından uygulanan değişiklikleri kolayca geri alabileceğinizden emin olun. Projeniz henüz kaynak denetimi altında değilse şimdi başlamanın tam zamanı. Herhangi bir nedenle bunu yapmak istemezseniz 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öntemlerin çağrılarını kaldırmanızı öneririz. Taşıma işlemi için komut dosyasını kullanmak istiyorsanız güncellediğiniz sürümü, komut dosyası tarafından yönetilen sürümle eşleştirmeniz gerekir.

    • Uygulamanızın derlemeSdkVersion değerini en az 32'ye yükseltin.

    • Gradle ve Android Studio Gradle eklentisini, yukarıdaki güncellenmiş bağımlılıklarla çalışan en son 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 (*) 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 - com.google.android.exoplayer2.StyledPlayerView arasında geçiş yapın. AndroidX Media3'te com.google.android.exoplayer2.PlayerView'ye eşdeğer bir değer olmadığı için bu gereklidir.

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

Komut dosyası, com.google.android.exoplayer2'ten 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'de yazılmış bir Android gradle projesinin kaynaklarında yeniden adlandırılmış sınıf ve paket 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 komut dosyasını --help ile çalıştırın.

  4. Taşıma için seçilen dosya grubunu listelemek üzere komut dosyasını -l ile çalıştırın (listeleme işlemini uyarı olmadan 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 ile eşlemek için komut dosyasını -m ile çalıştırın. Komut dosyası -m seçeneğiyle çalıştırıldığında değişiklikler seçilen dosyalara uygulanır.

    • Değişiklik yapmadan doğrulama hatasında durun
    ./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 zorunlu kılınabilir:

    ./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. Skriptin kodunuzu nasıl değiştirdiğini kontrol edin: Bir karşılaştırma aracı kullanın ve olası sorunları düzeltin (Skriptte, -f seçeneği ile aktarılmayan genel bir sorun olduğunu düşünüyorsanız bir hata kaydı gönderebilirsiniz).
  2. Projeyi derleyin: ./gradlew clean build'yi kullanın veya Android Studio'da Dosya > Projeyi Gradle Dosyalarıyla Senkronize Et'i, ardından Derle > Projeyi temizle'yi ve ardından Derle > Projeyi yeniden derle'yi seçin (Android Studio'nun "Derleme - Derleme Çıktısı" sekmesinde derleme işleminizi izleyin.

Önerilen takip adımları:

  1. Kararlı olmayan API'lerin kullanımıyla ilgili hataları 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 işaretçiyi uyarının üzerine getirin ve belirli bir çağrı yerine ne kullanılacağını öğrenmek için desteği sonlandırılan sembolün JavaDoc'una bakın.
  3. İçe aktarma ifadelerini sıralayın: Projeyi Android Studio'da açın, ardından proje görüntüleyicisindeki bir paket klasörünü sağ tıklayın ve değiştirilen kaynak dosyaları içeren paketlerde İçe aktarma işlemlerini 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 denetleyicilerden, uygun oynatıcı yöntemlerine yetki verilmesi gereken komutları almaktan sorumluydu. AndroidX Media3 ile bu işlem, konnektör gerektirmeden doğrudan MediaSession tarafından yapılır.

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

  2. Bağımlılıklarınızı depoladığınız 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.4.1"
    
  3. MediaSessionCompat yerine androidx.media3.session.MediaSession yazın.

  4. Eski MediaSessionCompat'yi oluşturduğunuz kod sitesinde, androidx.media3.session.MediaSession.Builder'ı kullanarak MediaSession oluşturun. Oturum oluşturucuyu oluşturmak için oynatıcıyı iletin.

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

  6. Taşıma işleminden önce, oturumunuzu kaldırdığınız kod sitesinde medya oturumunu serbest bırakın:

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

Media3'te MediaSessionConnector işlevi

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

MediaSessionConnectorAndroidX Medya 3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setCustomLayout()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() şirket içinde çağrılır)
QueueNavigator ForwardingPlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

MediaBrowserServiceMediaLibraryService'e taşıma

AndroidX Media3, MediaBrowserServiceCompat yerine MediaLibraryService ürününü kullanıma sundu. MediaLibraryService ve üst sınıfı MediaSessionService'ün JavaDoc'u, API'ye ve hizmetin asenkron programlama modeline dair iyi bir giriş sunar.

MediaLibraryService, MediaBrowserService ile geriye dönük uyumludur. MediaBrowserCompat veya MediaControllerCompat kullanan bir istemci uygulaması, MediaLibraryService'ye bağlanırken kod değişikliği olmadan çalışmaya devam eder. Uygulamanızın MediaLibraryService mi yoksa eski MediaBrowserServiceCompat mi kullandığı istemci için şeffaftır.

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'de her iki hizmet arayüzünü de hizmetinize kaydettirmeniz gerekir. Bu sayede istemci, gerekli hizmet arayüzüne göre hizmetinizi 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ı depoladığınız 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.4.1"
    
  3. Hizmetinizi, MediaBrowserService yerine MediaLibraryService'dan devralacak şekilde değiştirin. Daha önce de belirtildiği gibi, MediaLibraryService eski MediaBrowserService ile uyumludur. Buna göre, hizmetin müşterilere sunduğu daha kapsamlı API hâlâ aynı. Bu nedenle, bir uygulamanın MediaBrowserService'ü uygulamak için gereken mantığın çoğunu koruyup yeni MediaLibraryService için uyarlaması olasıdır.

    Eski MediaBrowserServiceCompat ile karşılaştırıldığında temel farklılıklar şunlardır:

    • Hizmet yaşam döngüsü yöntemlerini uygulayın: Hizmetin kendisinde geçersiz kılınması gereken yöntemler, uygulamanın kitaplık oturumunu, oynatıcıyı ve diğer kaynakları ayırdığı/saldığını belirten onCreate/onDestroy yöntemleridir. Standart hizmet yaşam döngüsü yöntemlerine ek olarak, bir uygulamanın onCreate içinde oluşturulan MediaLibrarySession değerini döndürmek için onGetSession(MediaSession.ControllerInfo) değerini geçersiz kılması gerekir.

    • MediaLibraryService.MediaLibrarySessionCallback'i uygulayın: Oturum oluşturmak için gerçek alan API 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ılarsınız.

      Ardından geri çağırma işlevi, MediaLibrarySession öğesini oluşturmak için kullanılır:

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

      MediaLibrarySessionCallback'in tam API'sini API belgelerinde bulabilirsiniz.

    • MediaSession.Callback.onAddMediaItems() yöntemini uygulayın: onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) geri çağırma işlevi, oynatıcıya geriye dönük uyumlu bir şekilde oynatılmak üzere medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Buna Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemlerinin yanı sıra eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri de dahildir. Geri çağırma işlevinin örnek bir uygulamasını oturum demo uygulamasının PlaybackService bölümünde bulabilirsiniz.

    • AndroidX Media3, MediaBrowserCompat.MediaItem ve MediaMetadataCompat yerine androidx.media3.common.MediaItem kullanıyor. Eski sınıflara bağlı kod parçalarınızın buna göre değiştirilmesi veya Media3 MediaItem ile eşlenmesi gerekir.

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

PlayerNotificationManager'ı kaldırma

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

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

MediaLibraryService.updateNotification() değerini geçersiz kılarak uygulama, bildirim yayınlama ve gerektiğinde hizmeti ön planda başlatma/durdurma işlemlerinin tam kontrolünü ele alabilir.

MediaBrowser kullanarak istemci kodunu taşıma

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

Bir MediaBrowser oluşturulabilir ve hizmete bağlantı kurulmasını bekleyebilir:

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'i nasıl oluşturacağınızı öğrenmek üzere Medya oturumunda oynatmayı kontrol etme başlıklı makaleyi inceleyin.

Daha fazla işlem yapın ve yer açın

Kararsız API hataları

Media3'e geçtikten sonra kararsız API kullanımlarıyla ilgili lint hataları görebilirsiniz. Bu API'lerin kullanımı güvenlidir ve lint hataları, yeni ikili uyumluluk garantilerimizin bir yan ürünüdür. Katı ikili uyumluluğu gerekmiyorsa bu hatalar bir @OptIn ek açıklamasıyla güvenli bir şekilde bastırılabilir.

Arka plan

ExoPlayer v1 veya v2, kitaplığın sonraki sürümler arasında ikili uyumluluğu hakkında katı garantiler sağlamadı. ExoPlayer API yüzeyi, uygulamaların oynatmanın neredeyse her yönünü özelleştirmesine olanak tanımak için tasarlandığından çok geniştir. ExoPlayer'ın sonraki sürümleri, zaman zaman sembol yeniden adlarını veya zarar veren diğer değişiklikleri (ör. arayüzlerde yeni gerekli yöntemler) kullanıma sunar. Çoğu durumda bu kesintiler, yeni simgenin kullanıma sunulması ve birkaç sürümde eski simgenin kullanımdan kaldırılmasıyla azaltılarak geliştiricilere kullanımlarını taşımaları için zaman tanımakla birlikte bu durum her zaman mümkün olmuyordu.

Bu zarar veren değişiklikler, ExoPlayer v1 ve v2 kitaplıkları kullanıcıları için iki soruna yol açmıştır:

  1. ExoPlayer sürümüne yükseltme yapmak, kodun derlemeyi durdurmasına neden olabilir.
  2. Hem doğrudan hem de ara kitaplık üzerinden ExoPlayer'a bağımlı olan bir uygulamanın, her iki bağımlılığın da aynı sürümde olduğundan emin olması gerekiyordu. Aksi takdirde ikili program uyumsuzlukları çalışma zamanında kilitlenmelere neden olabilirdi.

Media3'te yapılan iyileştirmeler

Media3, API yüzeyinin bir alt kümesi için ikili program uyumluluğunu garanti eder. İkili uyumluluğu garanti etmeyen parçalar @UnstableApi ile işaretlenmiştir. Bu ayrımı netleştirmek için kararsız API simgelerinin kullanımı, @OptIn ile ek açıklama yapılmadığı sürece lint hatası oluşturur.

ExoPlayer v2'den Media3'e geçtikten sonra birçok kararsız API lint hatası görebilirsiniz. Bu durum, Media3'ün ExoPlayer v2'den "daha kararsız" olduğu izlenimi verebilir. Böyle bir durum söz konusu değildir. Media3 API'nin "dengeli olmayan" bölümleri, 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. Tek fark, artık lint hatalarının farklı kararlılık seviyeleri hakkında sizi uyarmasıdır.

Kararsız API lint hatalarını giderme

Kararsız API'lerin Java ve Kotlin kullanımlarının @OptIn ile nasıl ek açıklamayla belirtileceği 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ılmış API'ler

Desteği sonlandırılan API'lere yapılan çağrıların Android Studio'da üstü çizildiğini fark edebilirsiniz. Bu tür çağrıları uygun alternatiflerle değiştirmenizi öneririz. Bunun yerine hangi API'nin kullanılacağını belirten JavaDoc'u görmek için fareyle sembolün üzerine gelin.

Ekran görüntüsü: Desteği sonlandırılan yöntemin alternatifiyle JavaDoc&#39;u görüntüleme
Şekil 3: Android Studio'daki JavaDoc ipucunda, desteği sonlandırılan semboller için alternatifler önerilir.

Kod örnekleri ve demo uygulamaları