Exoplayer: Is it recommended to release the player when activity goes onPause()? onStop()?

Created on 20 Mar 2020  路  6Comments  路  Source: google/ExoPlayer

What is the recommendation of the ExoPlayer developers regarding releasing the player? Is it recommended to do it systematically in the activity's onPause()? onStop()? onDestroy()? I can see that releasing in onPause() seems to be the default practice in most demo apps, but I would like to understand why.

In my ExoPlayer-based app running on Android N, I would like the playback to resume as fast as possible after a dialog appears (onPause()/onResume() case), but also after someone calls the user for example (onStop()/onStart() case). Does it seem reasonable to release the player only in onDestroy()? Can it result into a memory leak? What is the player's memory footprint? (not counting the buffer).

Thanks.

question

All 6 comments

The PlayerActivity of the demo application implements it in the recommended way.

With API 24 multi window was introduced to Android. This means that two apps can be visible at the same time. This has changed things and that's why the behaviour is different for API < 24. After 24 you want to release the player in onStop, because onPause may be called when your app is still visible in split screen.

Before API 24 you need to do this in onPause because there is no guarantee that onStop is called at all. Also, you need to release in onPause because then it is guaranteed that stopping your app does not overlap with starting another app. Overlapping needs to be avoided because both apps may want to acquire hardware codecs for which only a limited number of instances are available (like only one on low-end devices).

onDestroy may not be called at all. You should not use it for freeing resources in general.

The memory footprint can be audited with Android Studio performance tools.

Closing this issue due to inactivity. Please reopen if required.

About onDestroy from docs:
There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.

That's why onDestroy is not guaranteed. When process is killed then all objects(player) are killed. 'onDestroy' event doesn't matter in this situation.

So what is the point to release player in onStop?

@Valgaal - I'm not sure what your question is. @marcbaechinger already describes the recommended approach above. There are no guarantees that onDestroy will be called soon enough for your app or activity to free resources (e.g., hardware codecs) that another app or activity coming into the foreground might want to use. Hence the need to use onStop or onPause instead, depending on API level.

This requirement is completely unrelated to what happens in the case that your process is killed, so I don't think the documentation you quote is relevant.

What will happen if second app wants hardware codecs, but the first app holds them?

I think the answer is that it depends. Some devices will successfully instantiate multiple codecs, in which case it will work fine. Unfortunately I don't think there's a good way to determine whether this will be the case, because the number that can be instantiated successfully can depend on the media for which they're configured.

If the codec can't be instantiated successfully then the app will fail to obtain the instances it wants. It may opt to retry, depending on implementation (or the user may retry with some UI that the app makes available). On more recent devices (API level 23 and above) this likely will allow successful playback because the underlying platform will reclaim the codecs from your now backgrounded process (this will cause the instances that your backgrounded app holds to become unusable, and future attempts to use them will cause ERROR_RECLAIMED failures). On older devices (pre API level 23) it's likely that the foreground app will just be unable to obtain the instances.

Note that even in the best case, you will increase the latency required for the foreground app to start playback. To be a good citizen, you should really follow the recommended approach.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

orcunkobal picture orcunkobal  路  3Comments

0x410c picture 0x410c  路  3Comments

KenendZ picture KenendZ  路  3Comments

noamtamim picture noamtamim  路  3Comments

mkaflowski picture mkaflowski  路  3Comments