MediaSessionService START_STICKY causes flaky restart behavior for apps with other foreground services
@marcbaechinger is already working on this.
Since Jun 13, 2023.
- Dominant language
- Java
- Stars
- 3k
- Forks
- 955
- Avg merge
- 12d 14h
- Merged PRs (30d)
- 2
Description
Media3 Version
Media3 1.0.2
Devices that reproduce the issue
Emulator API levels 27-33
Devices that do not reproduce the issue
Emulator API 26 & API 34 (Beta 3)
Reproducible in the demo app?
Not tested
Reproduction steps
Minimal repro project at https://github.com/bubenheimer/multifgsvcbugs
This project does not actually use MediaSessionService, but demonstrates the general problem. It has 2 START_STICKY services that, at times, are intended to run as foreground services. DataSyncService runs as a foreground service from onCreate() to onDestroy(), while SoundService does not initially run as a foreground service, but is intended to be running as a foreground service at various times. (The startForeground() code to make it a foreground service is commented out, it's not what I want to demonstrate here.) SoundService is meant to represent a MediaSessionService instance that is not currently running as a foreground service.
- Start app.
- Tap "Request POST_NOTIFICATIONS permission" for API 33+ (optional, to see foreground service notification).
- Tap "Start data sync service".
- Tap "Start sound service".
- Simulate the system being under memory pressure and killing the process that the 2 services run in (
org.bubenheimer:ext). I believe this corresponds to "am kill". There are various ways to do this. ("Force stop" is NOT one of them.) I prefer doing it from the "Device Explorer" tab in Android Studio Giraffe+ ("Kill process" under "Processes"), but it may be possible from Logcat as well. Or "kill -9".
Expected result
In Logcat, observe process being killed and recreated shortly thereafter, and DataSyncService and SoundService logging from onCreate().
Actual result
Intermittently DataSyncService is not restarted automatically, only SoundService is recreated. Sometimes other weird stuff happens, e.g. onCreate() followed by instant onDestroy()`.
This can take several app runs to show up.
This behavior is not really the fault of MediaSessionService, it's an Android framework bug (and seems fixed in API 34). The problematic thing in MediaSessionService is its use of START_STICKY, which is the primary thing triggering the behavior. Of course, an overriding MediaSessionService instance can choose to return whatever it wants from onStartCommand().
Returning START_NOT_STICKY generally helps avoid the issue, at least to some degree. (In my complex production services setup it does not clear up the problem, but it does help.)
Is the use of START_STICKY in MediaSessionService intentional and recommended? Or is it optional or arbitrary and can be replaced?
Does MediaSessionService use START_STICKY because it restores some saved state upon automatic recreation after process death? I have not seen this myself, but I'd be interested in a pointer if it does.
Having more than one foreground service in an app is not so common because they can usually be combined. However, MediaSessionService (and MediaBrowserService, MediaBrowserServiceCompat, etc.) does not lend itself to combining, because it generally is exported. (Also I'd think it is not really designed to be flexibly combined with arbitrary other services that have different bind/unbind/start/stop lifecycles.)
Media
N/A
Bug Report
- You will email the zip file produced by
adb bugreportto dev.exoplayer@gmail.com after filing this issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.