1*30877f79SAndroid Build Coastguard Worker--- 2*30877f79SAndroid Build Coastguard Workertitle: APK shrinking 3*30877f79SAndroid Build Coastguard Worker--- 4*30877f79SAndroid Build Coastguard Worker 5*30877f79SAndroid Build Coastguard WorkerMinimizing APK size is an important aspect of developing a good Android 6*30877f79SAndroid Build Coastguard Workerapplication. This is particularly true when targeting developing markets, and 7*30877f79SAndroid Build Coastguard Workeralso when developing an Android Instant App. For such cases it may be desirable 8*30877f79SAndroid Build Coastguard Workerto minimize the size of the ExoPlayer library that's included in the APK. This 9*30877f79SAndroid Build Coastguard Workerpage outlines some simple steps that can help to achieve this. 10*30877f79SAndroid Build Coastguard Worker 11*30877f79SAndroid Build Coastguard Worker## Use modular dependencies ## 12*30877f79SAndroid Build Coastguard Worker 13*30877f79SAndroid Build Coastguard WorkerThe most convenient way to use ExoPlayer is to add a dependency to the full 14*30877f79SAndroid Build Coastguard Workerlibrary: 15*30877f79SAndroid Build Coastguard Worker 16*30877f79SAndroid Build Coastguard Worker~~~ 17*30877f79SAndroid Build Coastguard Workerimplementation 'com.google.android.exoplayer:exoplayer:2.X.X' 18*30877f79SAndroid Build Coastguard Worker~~~ 19*30877f79SAndroid Build Coastguard Worker{: .language-gradle} 20*30877f79SAndroid Build Coastguard Worker 21*30877f79SAndroid Build Coastguard WorkerHowever this may pull in more features than your app needs. Instead, depend only 22*30877f79SAndroid Build Coastguard Workeron the library modules that you actually need. For example the following will 23*30877f79SAndroid Build Coastguard Workeradd dependencies on the Core, DASH and UI library modules, as might be required 24*30877f79SAndroid Build Coastguard Workerfor an app that only plays DASH content: 25*30877f79SAndroid Build Coastguard Worker 26*30877f79SAndroid Build Coastguard Worker~~~ 27*30877f79SAndroid Build Coastguard Workerimplementation 'com.google.android.exoplayer:exoplayer-core:2.X.X' 28*30877f79SAndroid Build Coastguard Workerimplementation 'com.google.android.exoplayer:exoplayer-dash:2.X.X' 29*30877f79SAndroid Build Coastguard Workerimplementation 'com.google.android.exoplayer:exoplayer-ui:2.X.X' 30*30877f79SAndroid Build Coastguard Worker~~~ 31*30877f79SAndroid Build Coastguard Worker{: .language-gradle} 32*30877f79SAndroid Build Coastguard Worker 33*30877f79SAndroid Build Coastguard Worker## Enable code and resource shrinking ## 34*30877f79SAndroid Build Coastguard Worker 35*30877f79SAndroid Build Coastguard WorkerYou should enable code and resource shrinking for your application's release 36*30877f79SAndroid Build Coastguard Workerbuilds. ExoPlayer is structured in a way that allows code shrinking to 37*30877f79SAndroid Build Coastguard Workereffectively remove unused functionality. For example, for an application that 38*30877f79SAndroid Build Coastguard Workerplays DASH content, ExoPlayer's contribution to APK size can be reduced by 39*30877f79SAndroid Build Coastguard Workerapproximately 40% by enabling code shrinking. 40*30877f79SAndroid Build Coastguard Worker 41*30877f79SAndroid Build Coastguard WorkerRead [Shrink, obfuscate, and optimize your app][] on the Android Developer site 42*30877f79SAndroid Build Coastguard Workerto learn how to enable code and resource shrinking. 43*30877f79SAndroid Build Coastguard Worker 44*30877f79SAndroid Build Coastguard Worker## Specify which renderers your app needs ## 45*30877f79SAndroid Build Coastguard Worker 46*30877f79SAndroid Build Coastguard WorkerBy default, the player's renderers will be created using 47*30877f79SAndroid Build Coastguard Worker`DefaultRenderersFactory`. `DefaultRenderersFactory` depends on all of the 48*30877f79SAndroid Build Coastguard Worker`Renderer` implementations provided in the ExoPlayer library, and as a result 49*30877f79SAndroid Build Coastguard Workernone of them will be removed by code shrinking. If you know that your app only 50*30877f79SAndroid Build Coastguard Workerneeds a subset of renderers, you can specify your own `RenderersFactory` 51*30877f79SAndroid Build Coastguard Workerinstead. For example, an app that only plays audio can define a factory like 52*30877f79SAndroid Build Coastguard Workerthis when instantiating `ExoPlayer` instances: 53*30877f79SAndroid Build Coastguard Worker 54*30877f79SAndroid Build Coastguard Worker~~~ 55*30877f79SAndroid Build Coastguard WorkerRenderersFactory audioOnlyRenderersFactory = 56*30877f79SAndroid Build Coastguard Worker (handler, videoListener, audioListener, textOutput, metadataOutput) 57*30877f79SAndroid Build Coastguard Worker -> new Renderer[] { 58*30877f79SAndroid Build Coastguard Worker new MediaCodecAudioRenderer( 59*30877f79SAndroid Build Coastguard Worker context, MediaCodecSelector.DEFAULT, handler, audioListener) 60*30877f79SAndroid Build Coastguard Worker }; 61*30877f79SAndroid Build Coastguard WorkerExoPlayer player = 62*30877f79SAndroid Build Coastguard Worker new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build(); 63*30877f79SAndroid Build Coastguard Worker~~~ 64*30877f79SAndroid Build Coastguard Worker{: .language-java} 65*30877f79SAndroid Build Coastguard Worker 66*30877f79SAndroid Build Coastguard WorkerThis will allow other `Renderer` implementations to be removed by code 67*30877f79SAndroid Build Coastguard Workershrinking. In this particular example video, text and metadata renderers are 68*30877f79SAndroid Build Coastguard Workerremoved. 69*30877f79SAndroid Build Coastguard Worker 70*30877f79SAndroid Build Coastguard Worker## Specify which extractors your app needs ## 71*30877f79SAndroid Build Coastguard Worker 72*30877f79SAndroid Build Coastguard WorkerBy default, the player will create `Extractor`s to play progressive media using 73*30877f79SAndroid Build Coastguard Worker`DefaultExtractorsFactory`. `DefaultExtractorsFactory` depends on all of the 74*30877f79SAndroid Build Coastguard Worker`Extractor` implementations provided in the ExoPlayer library, and as a result 75*30877f79SAndroid Build Coastguard Workernone of them will be removed by code shrinking. If you know that your app only 76*30877f79SAndroid Build Coastguard Workerneeds to play a small number of container formats, or doesn't play progressive 77*30877f79SAndroid Build Coastguard Workermedia at all, you can specify your own `ExtractorsFactory` instead. For example, 78*30877f79SAndroid Build Coastguard Workeran app that only needs to play mp4 files can provide a factory like: 79*30877f79SAndroid Build Coastguard Worker 80*30877f79SAndroid Build Coastguard Worker~~~ 81*30877f79SAndroid Build Coastguard WorkerExtractorsFactory mp4ExtractorFactory = 82*30877f79SAndroid Build Coastguard Worker () -> new Extractor[] {new Mp4Extractor()}; 83*30877f79SAndroid Build Coastguard WorkerExoPlayer player = 84*30877f79SAndroid Build Coastguard Worker new ExoPlayer.Builder( 85*30877f79SAndroid Build Coastguard Worker context, 86*30877f79SAndroid Build Coastguard Worker new DefaultMediaSourceFactory(context, mp4ExtractorFactory)) 87*30877f79SAndroid Build Coastguard Worker .build(); 88*30877f79SAndroid Build Coastguard Worker~~~ 89*30877f79SAndroid Build Coastguard Worker{: .language-java} 90*30877f79SAndroid Build Coastguard Worker 91*30877f79SAndroid Build Coastguard WorkerThis will allow other `Extractor` implementations to be removed by code 92*30877f79SAndroid Build Coastguard Workershrinking, which can result in a significant reduction in size. 93*30877f79SAndroid Build Coastguard Worker 94*30877f79SAndroid Build Coastguard WorkerIf your app is not playing progressive content at all, you should pass 95*30877f79SAndroid Build Coastguard Worker`ExtractorsFactory.EMPTY` to the `DefaultMediaSourceFactory` constructor, then 96*30877f79SAndroid Build Coastguard Workerpass that `mediaSourceFactory` to the `ExoPlayer.Builder` constructor. 97*30877f79SAndroid Build Coastguard Worker 98*30877f79SAndroid Build Coastguard Worker~~~ 99*30877f79SAndroid Build Coastguard WorkerExoPlayer player = 100*30877f79SAndroid Build Coastguard Worker new ExoPlayer.Builder( 101*30877f79SAndroid Build Coastguard Worker context, 102*30877f79SAndroid Build Coastguard Worker new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)) 103*30877f79SAndroid Build Coastguard Worker .build(); 104*30877f79SAndroid Build Coastguard Worker~~~ 105*30877f79SAndroid Build Coastguard Worker{: .language-java} 106*30877f79SAndroid Build Coastguard Worker 107*30877f79SAndroid Build Coastguard Worker## Custom `MediaSource` instantiation ## 108*30877f79SAndroid Build Coastguard Worker 109*30877f79SAndroid Build Coastguard WorkerIf your app is using a custom `MediaSource.Factory` and you want 110*30877f79SAndroid Build Coastguard Worker`DefaultMediaSourceFactory` to be removed by code stripping, you should pass 111*30877f79SAndroid Build Coastguard Workeryour `MediaSource.Factory` directly to the `ExoPlayer.Builder` constructor. 112*30877f79SAndroid Build Coastguard Worker 113*30877f79SAndroid Build Coastguard Worker~~~ 114*30877f79SAndroid Build Coastguard WorkerExoPlayer player = 115*30877f79SAndroid Build Coastguard Worker new ExoPlayer.Builder(context, customMediaSourceFactory).build(); 116*30877f79SAndroid Build Coastguard Worker~~~ 117*30877f79SAndroid Build Coastguard Worker{: .language-java} 118*30877f79SAndroid Build Coastguard Worker 119*30877f79SAndroid Build Coastguard WorkerIf your app is using `MediaSource`s directly instead of `MediaItem`s you should 120*30877f79SAndroid Build Coastguard Workerpass `MediaSource.Factory.UNSUPPORTED` to the `ExoPlayer.Builder` constructor, 121*30877f79SAndroid Build Coastguard Workerto ensure `DefaultMediaSourceFactory` and `DefaultExtractorsFactory` can be 122*30877f79SAndroid Build Coastguard Workerstripped by code shrinking. 123*30877f79SAndroid Build Coastguard Worker 124*30877f79SAndroid Build Coastguard Worker~~~ 125*30877f79SAndroid Build Coastguard WorkerExoPlayer player = 126*30877f79SAndroid Build Coastguard Worker new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build(); 127*30877f79SAndroid Build Coastguard WorkerProgressiveMediaSource mediaSource = 128*30877f79SAndroid Build Coastguard Worker new ProgressiveMediaSource.Factory( 129*30877f79SAndroid Build Coastguard Worker dataSourceFactory, customExtractorsFactory) 130*30877f79SAndroid Build Coastguard Worker .createMediaSource(MediaItem.fromUri(uri)); 131*30877f79SAndroid Build Coastguard Worker~~~ 132*30877f79SAndroid Build Coastguard Worker{: .language-java} 133*30877f79SAndroid Build Coastguard Worker 134*30877f79SAndroid Build Coastguard Worker[Shrink, obfuscate, and optimize your app]: https://developer.android.com/studio/build/shrink-code 135