AndroidX Media3 taşıma kılavuzu

Şu anda bağımsız com.google.android.exoplayer2 kitaplığını ve androidx.media sürümünü kullanan uygulamalar androidx.media3 ürününe taşınmalıdır. Gradle derleme dosyalarını, Java ve Kotlin kaynak dosyalarını ve XML düzen dosyalarını ExoPlayer2.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, yeni API'lerin avantajları, taşınacak API'ler ve uygulamanızın projesinin 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çiş yapmalısınız?

  • Burası, ExoPlayer'ın yeni yeridir, ancak com.google.android.exoplayer2 kullanımdan kaldırılmıştır.
  • 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 uyumluluğa sahip (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ı olarak uygulama veya modüller, taşıma komut dosyasıyla taşınabilir.
  • MediaSessionConnector (androidx.media:media:1.4.3+ androidx.media.* paketlerine bağlı olarak)
    MediaSessionConnector öğesini kaldırın ve bunun yerine androidx.media3.session.MediaSession kullanın.
  • MediaBrowserServiceCompat (androidx.media:media:1.4.3+ adlı öğenin androidx.media.* paketlerine bağlı olarak)
    androidx.media.MediaBrowserServiceCompat alt sınıflarını androidx.media3.session.MediaLibraryService ve MediaBrowserCompat.MediaItem ile androidx.media3.common.MediaItem arasındaki kodu taşıyın.
  • MediaBrowserCompat (androidx.media:media:1.4.3+'ın android.support.v4.media.* paketlerine bağlı olarak)
    androidx.media3.session.MediaBrowser'yi androidx.media3.common.MediaItem ile kullanmak için MediaBrowserCompat veya MediaControllerCompat ile istemci kodunu taşıyın.

Ön koşullar

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

    Komut dosyası kullanılan taşıma araçları tarafından uygulanan değişiklikleri kolayca geri alabileceğinizden emin olun. Projeniz henüz kaynak kontrolü altında değilse projeye hemen başlayabilirsiniz. Herhangi bir nedenle bunu yapmak istemezseniz taşıma işlemine başlamadan önce projenizin yedek bir 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 kullanımdan kaldırılan yöntemlere yapılan tüm çağrıları kaldırmanızı öneririz. Taşıma işlemi için komut dosyasını kullanmayı planlıyorsanız güncelleme yaptığınız sürümü, komut dosyası tarafından işlenen sürümle eşleştirmeniz gerekir.

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

    • Gradle'ı ve Android Studio Gradle eklentisini, yukarıda belirtilen güncel bağımlılıklarla çalışan yeni bir sürüme geçirin. Örneğin:

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

    • com.google.android.exoplayer2.PlayerView'ten com.google.android.exoplayer2.StyledPlayerView'e geçiş. Bu, AndroidX Media3'te com.google.android.exoplayer2.PlayerView eşdeğeri olmadığından gereklidir.

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

Komut dosyası, com.google.android.exoplayer2 ürününden androidx.media3 altındaki yeni paket ve modül yapısına geçişi kolaylaştırır. Komut dosyası, projenize 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ı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 taşıma komut dosyasını GitHub'daki ExoPlayer projesinin etiketinden 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 (girişi uyarı yapılmadan zorlamak için -f kodunu 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çili dosyalara uygulanır.

    • Doğrulama hatasında değişiklik yapmadan durdur
    ./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 bu manuel adımları tamamlayın:

  1. Komut dosyasının kodunuzu nasıl değiştirdiğini kontrol edin: Bir fark aracı kullanın ve olası sorunları düzeltin (komut dosyasının -f seçeneği geçilmeden ortaya çıkan genel bir sorunu olduğunu düşünüyorsanız hata bildirmeyi düşünün).
  2. Projeyi oluşturma: ./gradlew clean build komutunu kullanın veya Android Studio'da Dosya > Projeyi Gradle Dosyaları ile Senkronize Et'i, ardından Derleme > Projeyi temizle'yi ve Derleme > Projeyi yeniden oluştur'u seçin (Derlemenizi Android Studio'nun "Derleme - Çıktı" sekmesinden izleyin.

Takip edilmesi önerilen adımlar:

  1. Kararsız API'lerin kullanımıyla ilgili hataları etkinleştirme sorununu çözün.
  2. Kullanımdan kaldırılan API çağrılarını değiştirme: Önerilen değişim API'sini kullanın. İşaretçiyi Android Studio'daki uyarının üzerine getirin ve belirli bir çağrı yerine ne kullanacağınızı öğrenmek için kullanımdan kaldırılan simgenin JavaDoc'una 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 aktarma işlemlerini optimize et'i seçin.

MediaSessionConnector yerine androidx.media3.session.MediaSession kullanın

Eski MediaSessionCompat dünyasında MediaSessionConnector, oynatıcının durumunu oturumun durumuyla senkronize etmekten ve uygun oynatıcı yöntemlerine yetki verilmesi gereken kumandalardan komut almaktan sorumluydu. AndroidX Media3'te bu işlem doğrudan MediaSession tarafından bağlayıcı gerektirmeden 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ı kullandıysanız komut dosyası, muhtemelen kodunuzu, çözülemeyen MediaSessionConnector ile ilgili derlenemez bir durumda bırakmıştır. Android Studio, uygulamayı derlemeye veya başlatmaya çalışırken bozuk kodu gösterir.

  2. Bağımlılıklarınızı yönettiğiniz build.gradle dosyasında, 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.2.1"
    
  3. MediaSessionCompat kısmını androidx.media3.session.MediaSession ile değiştirin.

  4. Eski MediaSessionCompat kodunu oluşturduğunuz kod sitesinde MediaSession oluşturmak için androidx.media3.session.MediaSession.Builder kodunu kullanın. 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()
    
    ForwardingPlayer(player)
  5. MySessionCallback işlevini uygulamanızın gerektirdiğ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() uygulayın. Medya öğelerini geriye dönük olarak uyumlu bir şekilde oynatmak üzere oynatıcıya ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemleri ve eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri buna dahildir. Örnek bir onAddMediaItems 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 yayınlayın:

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

Media3'te MediaSessionConnector işlevi

Aşağıdaki tabloda daha önce MediaSessionConnector ürününde uygulanmış olan işlevleri kullanan Media3 API'leri gösterilmektedir.

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

MediaBrowserService adlı kişiyi MediaLibraryService alanına taşıyın

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

MediaLibraryService, MediaBrowserService ile geriye dönük uyumluluğa sahiptir. MediaBrowserCompat veya MediaControllerCompat kullanan bir istemci uygulaması, MediaLibraryService bağlanırken kod değişikliği olmadan çalışmaya devam eder. İstemci için uygulamanızın MediaLibraryService veya eski MediaBrowserServiceCompat kullanması şeffaftır.

Hizmet, etkinlik ve harici uygulamaları içeren uygulama bileşen şeması.
Şekil 1: Medya uygulaması bileşenine genel bakış
  1. Geriye dönük uyumluluğun çalışması için AndroidManifest.xml içinde hizmetinize her iki hizmet arayüzünü kaydetmeniz gerekir. Bu şekilde istemci, gerekli hizmet arayüzünden yararlanarak 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ı yönettiğiniz build.gradle dosyasında, 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.2.1"
    
  3. MediaBrowserService yerine hizmetinizi MediaLibraryService öğesinden devralacak şekilde değiştirin Daha önce de belirtildiği gibi, MediaLibraryService eski MediaBrowserService ile uyumludur. Bu doğrultuda, hizmetin müşterilere sunduğu daha kapsamlı API hâlâ aynı. Bu nedenle, büyük olasılıkla bir uygulama, MediaBrowserService öğesini uygulamak ve yeni MediaLibraryService için uyarlamak için gereken mantığın çoğunu koruyabilir.

    Eski MediaBrowserServiceCompat ile karşılaştırıldığında temel farklılıklar aşağıda belirtilmiştir:

    • Hizmet yaşam döngüsü yöntemlerini uygulama: Hizmetin kendisinde geçersiz kılınması gereken yöntemler onCreate/onDestroy; bu durumda 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 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: Oturum oluşturmak için gerçek alan API yöntemlerini uygulayan bir MediaLibraryService.MediaLibrarySessionCallback gereklidir. Dolayısıyla eski hizmetin API yöntemlerini geçersiz kılmak yerine MediaLibrarySession.Callback yöntemini geçersiz kılarsınız.

      Geri çağırma, daha sonra MediaLibrarySession 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() uygulayın: Geri çağırma (onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)), geriye dönük uyumlu olarak oynatılmak üzere oynatıcıya medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemleri ve eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri buna dahildir. Geri çağırmanın örnek 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ır. Kodunuzun eski sınıflara bağlı bazı bölümlerinin uygun şekilde değiştirilmesi veya bunun yerine Media3 MediaItem ile eşlenmesi gerekir.

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

PlayerNotificationManager'ı Kaldır

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

Bir uygulama, onCreate() ürününde DefaultMediaNotificationProvider öğesinin yerine geçen özel bir MediaNotification.Provider ayarlayarak bildirimi özelleştirebilir. Ardından MediaLibraryService, hizmetin gerektiği şekilde ön planda başlatılmasını üstlenir.

Bir uygulama MediaLibraryService.updateNotification() öğesini geçersiz kılarak, bildirim yayınlama ve hizmeti gerektiğinde ön planda başlatma/durdurma konusunda tam sahiplik alabilir.

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ı da kontrol etmek için kullanılabilir. Eski dünyada bir MediaBrowserCompat ve bir MediaControllerCompat oluşturmanız gerektiyse aynısını yalnızca Media3'te MediaBrowser kullanarak yapabilirsiniz.

Bir MediaBrowser derlenebilir ve kurulmakta olan hizmetle bağlantının 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 oluşturmayı öğrenmek amacıyla Medya oturumunda oynatmayı kontrol etme bölümüne göz atın.

Daha fazla adım atma 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'lerin kullanımı güvenlidir ve lint hataları, yeni ikili uyumluluk garantilerimizin yan ürünüdür. Katı ikili program uyumluluğuna ihtiyaç duymuyorsanız bu hatalar @OptIn ek açıklamasıyla güvenli bir şekilde giderilebilir.

Arka plan

ExoPlayer v1 veya v2, kitaplığın sonraki sürümler arasında ikili program uyumluluğu konusunda kesin garanti vermemiştir. ExoPlayer API yüzeyi, uygulamaların oynatmanın neredeyse her yönünü özelleştirebilmesi için tasarım gereği çok geniştir. ExoPlayer'ın sonraki sürümleri, zaman zaman sembol yeniden adlandırmaları veya zarar veren diğer değişiklikler (ör. arayüzlerde gerekli yeni yöntemler) uygular. Çoğu durumda, geliştiricilerin kullanımlarını taşımaları için zaman tanımak amacıyla eski sembolün kullanımdan kaldırılmasıyla birlikte yeni sembolün kullanıma sunulmasıyla bu bozulmalar azaltılıyordu. Ancak bu her zaman mümkün değildi.

Bu zarar veren 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ünden yapılan bir yükseltme, kodun derlemeyi durdurmasına neden olabilir.
  2. Hem doğrudan hem de ara bir kitaplık üzerinden ExoPlayer kullanan bir uygulama, her iki bağımlılığın da aynı sürümde olmasını sağlamak zorundaydı. Aksi takdirde ikili program uyumsuzlukları, çalışma zamanı kilitlenmelerine yol açabilirdi.

Media3'teki İyileştirmeler

Media3, API yüzeyinin bir alt kümesi için ikili uyumluluk garantisi verir. İkili program uyumluluğu garanti edilmeyen parçalar @UnstableApi ile işaretlenir. Bu ayrımı netleştirmek için kararsız API sembollerinin kullanımı, @OptIn ile ek açıklama yapılmadığı sürece hata analizi hatası oluşturur.

ExoPlayer v2'den Media3'e geçiş yaptıktan sonra çok sayıda kararsız API lint hatasıyla karşılaşabilirsiniz. Bu durum, Media3'ün ExoPlayer v2'ye göre "daha az kararlı" olmasına neden olabilir. Bu doğru değildir. Media3 API'nin "kararsız" kısımları, ExoPlayer v2 API yüzeyinin tamamıyla aynı kararlılık düzeyine sahiptir ve kararlı Media3 API yüzeyinin garantileri ExoPlayer v2'de hiç yoktur. Aralarındaki fark, bir lint hatasının artık sizi farklı kararlılık seviyeleriyle ilgili olarak uyarmasıdır.

Kararsız API lint hatalarını işleme

Kararsız API lint hatalarını ele almak için iki seçeneğiniz vardır:

  • Aynı sonucu elde eden kararlı bir API kullanmaya geçin.
  • Kararsız API'yi kullanmaya devam edin ve kullanımı @OptIn ile not ekleyin.

    import androidx.annotation.OptIn
    import androidx.media3.common.util.UnstableApi
    
    @OptIn(UnstableApi::class)
    fun functionUsingUnstableApi() {
      // Do something useful.
    }
    

    Kullanılmaması gereken bir kotlin.OptIn ek açıklaması da bulunduğunu lütfen unutmayın. Bunun için androidx.annotation.OptIn notuna bağlı kalmak önemlidir.

    Ekran görüntüsü: Etkinleştirme ek açıklaması nasıl eklenir?
    Şekil 2: Android Studio ile @androidx.annotations.OptIn ek açıklaması ekleme.

package-info.java ekleyerek tüm paketleri etkinleştirebilirsiniz:

@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

lint.xml dosyasındaki belirli lint hatası engellenerek projelerin tamamı dahil edilebilir. Daha fazla ayrıntı için UnstableApi ek açıklamasının JavaDoc'una bakın.

Kullanımdan Kaldırılan API'ler

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

Ekran görüntüsü: JavaDoc, kullanımdan kaldırılan bir yöntem yerine nasıl gösterilir?
Şekil 3: Android Studio'daki JavaDoc ipucu, kullanımdan kaldırılan simgeler için bir alternatif önerir.

Kod örnekleri ve demo uygulamaları