Riduzione APK

Ridurre al minimo le dimensioni dell'APK è un aspetto importante per sviluppare una buona app per Android. Questo è particolarmente vero quando ci si rivolge a mercati in via di sviluppo, nonché quando si sviluppa un'app istantanea Android. In questi casi, può essere utile ridurre al minimo le dimensioni della libreria ExoPlayer inclusa nell'APK. In questa pagina vengono descritti alcuni semplici passaggi che possono aiutarti a raggiungere questo obiettivo.

Utilizza solo le dipendenze richieste

Dipende solo dai moduli della libreria di cui hai effettivamente bisogno. Ad esempio, quanto segue aggiungerà dipendenze ai moduli ExoPlayer, DASH e della libreria UI, come potrebbe essere necessario per un'app che riproduce solo contenuti 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")

trendy

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"

Abilita la riduzione di codice e risorse

Devi abilitare la riduzione di codice e risorse per le build di release dell'app. ExoPlayer è strutturato in modo da consentire la riduzione del codice per rimuovere in modo efficace le funzionalità inutilizzate. Ad esempio, per un'app che riproduce contenuti DASH, il contributo di ExoPlayer alle dimensioni dell'APK può essere ridotto di circa il 40% abilitando la riduzione del codice.

Leggi Ridurre, offuscare e ottimizzare l'app per scoprire come attivare la riduzione di codice e risorse.

Specifica i renderer necessari per la tua app

Per impostazione predefinita, i renderer del player verranno creati utilizzando DefaultRenderersFactory. DefaultRenderersFactory dipende da tutte le implementazioni Renderer fornite nella libreria ExoPlayer e, di conseguenza, nessuna verrà rimossa dalla riduzione del codice. Se sai che la tua app ha bisogno solo di un sottoinsieme di renderer, puoi specificare il tuo RenderersFactory. Ad esempio, un'app che riproduce solo l'audio può definire un valore di fabbrica come questa per la creazione di un'istanza di ExoPlayer istanze:

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();

Ciò consentirà la rimozione di altre implementazioni Renderer mediante la riduzione del codice. In questo particolare esempio, i renderer di video e metadati vengono rimossi, il che significa che eventuali metadati dei sottotitoli o in-stream (ad es. ICY) non saranno elaborati o emessi dal player.

Specifica gli estrattori necessari per la tua app

Per impostazione predefinita, il player crea istanze Extractor per riprodurre contenuti multimediali progressivi utilizzando DefaultExtractorsFactory. DefaultExtractorsFactory dipende da tutte le implementazioni Extractor fornite nella libreria ExoPlayer e, di conseguenza, nessuna verrà rimossa dalla riduzione del codice. Se sai che la tua app deve riprodurre solo un numero limitato di formati container o non supporta alcun formato progressivo, puoi specificare il tuo ExtractorsFactory. Ad esempio, un'app che deve riprodurre soltanto file mp4 può fornire un prodotto di fabbrica come:

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();

Ciò consentirà la rimozione di altre implementazioni Extractor mediante la riduzione del codice, il che può comportare una riduzione significativa delle dimensioni.

Se l'app non riproduce contenuti progressivi, devi passare ExtractorsFactory.EMPTY al costruttore DefaultMediaSourceFactory, quindi passare questo mediaSourceFactory al costruttore 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();

Istanza MediaSource personalizzata

Se la tua app utilizza un MediaSource.Factory personalizzato e vuoi che DefaultMediaSourceFactory venga rimosso rimuovendo il codice, devi passare MediaSource.Factory direttamente al costruttore ExoPlayer.Builder.

Kotlin

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

Java

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

Se la tua app usa direttamente MediaSource anziché MediaItem, devi passare MediaSource.Factory.UNSUPPORTED al costruttore ExoPlayer.Builder, per assicurarti che DefaultMediaSourceFactory e DefaultExtractorsFactory possano essere rimossi dalla riduzione del codice.

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