Zmniejszanie pliku APK

Minimalizowanie rozmiaru pliku APK to ważny aspekt tworzenia dobrej aplikacji na Androida. Zdarza się to zwłaszcza w przypadku kierowania na rynki rozwijające się oraz tworzenia aplikacji błyskawicznej na Androida. W takich przypadkach warto zmniejszyć rozmiar biblioteki ExoPlayer zawartej w pliku APK. Na tej stronie opisujemy kilka prostych czynności, które mogą W tym pomóc.

Używaj tylko wymaganych zależności

W zależności od modułów biblioteki, których potrzebujesz. Na przykład poniższe zależności dodają zależności od modułów ExoPlayer, DASH i biblioteki interfejsu użytkownika, co może być wymagane w przypadku aplikacji odtwarzającej tylko treści DASH:

Kotlin

implementation("androidx.media3:media3-exoplayer:1.3.1")
implementation("androidx.media3:media3-exoplayer-dash:1.3.1")
implementation("androidx.media3:media3-ui:1.3.1")

Odlotowy

implementation "androidx.media3:media3-exoplayer:1.3.1"
implementation "androidx.media3:media3-exoplayer-dash:1.3.1"
implementation "androidx.media3:media3-ui:1.3.1"

Włącz zmniejszanie kodu i zasobów

Włącz zmniejszanie kodu i zasobów w kompilacjach wersji aplikacji. Platforma ExoPlayer ma taką strukturę, która umożliwia zmniejszenie kodu w celu efektywnego usuwania nieużywanych funkcji. Na przykład: w przypadku aplikacji, która odtwarza treści DASH, udział platformy ExoPlayer w rozmiarze pliku APK można zmniejszyć o około 40%, zmniejszając kod.

Przeczytaj artykuł Zmniejszanie, zaciemnianie i optymalizowanie aplikacji, aby dowiedzieć się, jak włączyć zmniejszanie kodu i zasobów.

Określanie, których mechanizmów renderowania potrzebuje Twoja aplikacja

Domyślnie mechanizmy renderowania odtwarzacza są tworzone za pomocą funkcji DefaultRenderersFactory. DefaultRenderersFactory zależy od wszystkich implementacji Renderer dostępnych w bibliotece ExoPlayer, dlatego żadna z nich nie zostanie usunięta w wyniku zmniejszania kodu. Jeśli wiesz, że aplikacja potrzebuje tylko podzbioru mechanizmów renderowania, możesz określić własny RenderersFactory. Na przykład aplikacja, która odtwarza tylko dźwięk, może zdefiniować fabrykę w następujący sposób podczas tworzenia instancji ExoPlayer:

Kotlin

val audioOnlyRenderersFactory =
  RenderersFactory {
    handler: Handler,
    videoListener: VideoRendererEventListener,
    audioListener: AudioRendererEventListener,
    textOutput: TextOutput,
    metadataOutput: MetadataOutput,
    ->
    arrayOf<Renderer>(
      MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, audioListener)
    )
}
val player = ExoPlayer.Builder(context, audioOnlyRenderersFactory).build()

Java

RenderersFactory audioOnlyRenderersFactory =
    (handler, videoListener, audioListener, textOutput, metadataOutput) ->
        new Renderer[] {
            new MediaCodecAudioRenderer(
                context, MediaCodecSelector.DEFAULT, handler, audioListener)
        };
ExoPlayer player = new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build();

Pozwoli to usuwać inne implementacje Renderer przez zmniejszenie kodu. W tym przykładzie zostały usunięte mechanizmy renderowania metadanych, co oznacza, że napisy i metadane In-Stream (np. ICY) nie będą przetwarzane ani wysyłane przez odtwarzacz.

Określ, których modułów wyodrębniania potrzebuje Twoja aplikacja

Domyślnie odtwarzacz tworzy instancje Extractor do odtwarzania multimediów progresywnych za pomocą DefaultExtractorsFactory. DefaultExtractorsFactory zależy od wszystkich implementacji Extractor dostępnych w bibliotece ExoPlayer, dlatego żadna z nich nie zostanie usunięta w wyniku zmniejszania kodu. Jeśli wiesz, że aplikacja musi odtwarzać niewielką liczbę formatów kontenera lub w ogóle nie odtwarza multimediów progresywnych, możesz określić własny ExtractorsFactory. Na przykład aplikacja, która musi odtwarzać tylko pliki mp4, może udostępniać ustawienia fabryczne:

Kotlin

val mp4ExtractorFactory = ExtractorsFactory {
  arrayOf<Extractor>(Mp4Extractor(DefaultSubtitleParserFactory()))
}
val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, mp4ExtractorFactory)).build()

Java

ExtractorsFactory mp4ExtractorFactory =
    () -> new Extractor[] {new Mp4Extractor(new DefaultSubtitleParserFactory())};
ExoPlayer player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, mp4ExtractorFactory))
        .build();

Pozwoli to usuwać inne implementacje Extractor przez zmniejszenie kodu, co może doprowadzić do znacznego zmniejszenia rozmiaru.

Jeśli aplikacja w ogóle nie odtwarza treści progresywnych, przekaż plik ExtractorsFactory.EMPTY do konstruktora DefaultMediaSourceFactory, a potem przekaż ten mediaSourceFactory do konstruktora ExoPlayer.Builder.

Kotlin

val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)).build()

Java

ExoPlayer player =
    new ExoPlayer.Builder(
            context, new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY))
        .build();

Utworzenie instancji niestandardowego MediaSource

Jeśli Twoja aplikacja korzysta z niestandardowego elementu MediaSource.Factory i chcesz, aby DefaultMediaSourceFactory został usunięty przez usunięcie kodu, przekaż MediaSource.Factory bezpośrednio do konstruktora ExoPlayer.Builder.

Kotlin

val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();

Jeśli Twoja aplikacja używa bezpośrednio protokołu MediaSource, a nie MediaItem, przekaż MediaSource.Factory.UNSUPPORTED do konstruktora ExoPlayer.Builder, aby zmniejszyć ryzyko DefaultMediaSourceFactory i DefaultExtractorsFactory.

Kotlin

val player = ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build()
val mediaSource =
  ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
    .createMediaSource(MediaItem.fromUri(uri))

Java

ExoPlayer player = new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build();
ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
        .createMediaSource(MediaItem.fromUri(uri));