问题
I have a started foreground service.
I've taken care to return START_STICKY from onStartCommand
.
I've observed that foreground services don't run indefinitely but are periodically terminated by an Android internal module called the RestartProcessManager
. Essentially a process LRU is maintained and the newly terminated service gets scheduled again if it's configured to do so(sticky or not).
The issue I'm facing is with how the restart is being handled. Logcat indicates the service intent was being delivered, but failed because the "process is bad"
After scouring through other sources I was led to believe that there's a memory leak within my service. To validate this claim I created a vanilla foreground service that did nothing other than log a statement during onStartCommand
within the same app. This too observed the same issue.
Tried the exact same thing in a new project (with a new package name obviously) and service restarts worked perfectly fine. Also, I simulate a restart by clicking the red cross button under studio->logcat (which essentially kills the process). Anyway, the service intent was successfully delivered this time and the service was up and running again. I assumed it could be some dependencies in my project that may be messing in some manner. I replicated the dependencies in the new project and it continued to work as expected.
Now this is where it gets absurd. I change the package name in the buggy project and I don't encounter the issue anymore. I'd have settled for this as a fix because I spent close to 2 days diagnosing this, but changing the package name isn't feasible for me as my app is published already.
Edit-1: I must mention that I've observed this currently on my device running Oreo(one plus 5)
Edit-2: The service is running in the same process as the app. And I've included the logcat dump as well.
02-15 14:26:50.850 1395 1445 D RestartProcessManager: updateSelf : com.ambee, size : 30
02-15 14:26:50.852 1395 1445 D RestartProcessManager: com.ambee got score 26.17240489145331 in DayDuration for duration : 525176
02-15 14:26:50.853 1395 1445 D RestartProcessManager: com.ambee got score 99.80218232889891 in DayLRU for LRU diff : 47707034
02-15 14:26:50.853 1395 1445 D RestartProcessManager: com.ambee got score 90.9090909090909 in DayLaunchTimes for launch times : 10
02-15 14:26:50.854 1395 1445 D RestartProcessManager: com.ambee : X : 2727.272727272727, Y : 785.1721467435993, Z : 2994.0654698669673
02-15 14:26:51.082 1395 1445 I ActivityManager: Killing 13839:com.ambee/u0a260 (adj 200): [BgDetect][RNK] kill com.ambee (uid 10260) usage 4
02-15 14:26:51.083 1395 1445 D ActivityManager: Process com.ambee has 1 services
02-15 14:26:51.083 1395 1445 W ActivityManager: Scheduling restart of crashed service com.ambee/.vson.LinkService in 10996ms
02-15 14:26:51.084 1395 1445 D EmbryoManager: prepare com.ambee user 0
02-15 14:26:51.099 3710 3710 D NotificationListener: onNotificationRemoved# hash: 68226270 sbn: StatusBarNotification(pkg=com.ambee user=UserHandle{0} id=903 tag=null key=0|com.ambee|903|null|10260: Notification(channel=default pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x72 color=0x00000000 actions=2 vis=PRIVATE))
02-15 14:26:54.121 1395 1444 I ActivityManager: Start proc 22570:com.ambee/u0a260 for embryo com.ambee
02-15 14:26:54.121 1395 1444 D Embryo_Uterus: Embryo created.com.ambee, pid=22570
02-15 14:26:54.796 22570 22570 D Embryo : preload com.ambee, 10ms, hwui=true, layout=false, decor=false
02-15 14:27:02.084 1395 1445 W ActivityManager: Unable to launch app com.ambee/10260 for service Intent { cmp=com.ambee/.vson.LinkService }: process is bad
02-15 14:27:04.214 1395 1444 D Embryo_Uterus: rank:63, com.ambee, 35767806
回答1:
For your vanilla version of your service, consider followings:
1- uninstall your app 2- reboot your device 3- reinstall your vanilla service version to just logging.
It should work.
For your foreground service consider using stopSelf or stopService methods and not stopForegroundService method. stopForegroundService just stop the service from being a foreground. It does not stop it from being a background service. It restarts over and over and if your service going to crash or not doing his job within 5 seconds, so OS kill your service over and over and eventually your service is going to blacklist of OS.
回答2:
Pushing up the comment of KR_Android : according to this blog and this other question : a service Intent is declared 'bad' after crashing at least twice.
Please try to
- Encapsulate all methods in
try { method(..); } catch(..) { log(..) }
security belts - Deinstall and reinstall the app
Let us know and we shall update our answers after digging further
回答3:
It annoyed me that the system wouldn't restart my service until I rebooted the box. Then I found this trick to clear the crash counts much more quickly:
adb shell killall system_server
来源:https://stackoverflow.com/questions/48615198/sticky-foreground-service-fails-to-restart-with-a-process-is-bad-error