35

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
Tamara Koliada
  • 1,200
  • 2
  • 14
  • 31
farthVader
  • 888
  • 11
  • 19
  • Have you tried de-installing the app with adb before reinstalling? I have sometimes issues that android is faking the uninstall and maybe there is something wrong with caches in the device or something. Also you need to call startForeground(context,Notification) within 5 seconds of calling startForegroundService(). But I guess you are doing that because otherwise you should get an ANR (at least this is the behaviour on 8.1). – Hendrik Marx Feb 09 '18 at 18:15
  • I have so far tried: uninstalling the app, restarting the phone, wiping the cache all to no effect. I am indeed calling startForeground in quick succession. – farthVader Feb 09 '18 at 18:30
  • 1
    Did your app crashed two times in short span before this problem? – KR_Android Feb 13 '18 at 16:06
  • Is your service running in a separate process? Please post the full logcat output where it states 'process is bad' – brandall Feb 15 '18 at 11:29
  • Related open bounty question? https://stackoverflow.com/q/48679603/1256219 – brandall Feb 15 '18 at 11:34
  • @brandall updated the post. And yes https://stackoverflow.com/q/48679603/1256219 seems like a possible duplicate. – farthVader Feb 15 '18 at 12:59
  • @KR_Android not sure. How would that affect things? – farthVader Feb 15 '18 at 12:59
  • Are you overriding `onTaskRemoved`. If so, remove it and see if the System restarts the Service correctly. – brandall Feb 15 '18 at 13:26
  • @brandall I am not overriding `onTaskRemoved` – farthVader Feb 15 '18 at 13:34
  • 1
    Are you using the new `startForegroundService(intent)` to initially start the Service? – brandall Feb 15 '18 at 13:36
  • One case in which any process is marked as "Bad process", app crashed twice in short span and on the crash dialog user pressed "Don't start". I am guessing, your old package name is marked as "bad process" and never reverted by the framework. This could be the reason why same code is working with different package name. I suggest you to try on other device or factory reset existing device :P – KR_Android Feb 15 '18 at 13:46
  • Also check if any power saving option is enabled in you phone? – KR_Android Feb 15 '18 at 13:53
  • @brandall tried it both ways(using plain old startService and using startForegroundService). Issue persists. – farthVader Feb 15 '18 at 16:30
  • @KR_Android this seems like the only logical explanation I've had so far. Is a factory reset the only way to go? – farthVader Feb 15 '18 at 16:31
  • I am just guessing, if this is your personal phone and factory reset can cause you loss of data, better try once on someone else phone once :D. BTW emulator is always there. – KR_Android Feb 15 '18 at 16:33
  • Have you tried a different device? Probably dumb question, but changing the package name resolving your issue would lead me to suspect something hanging on that shouldn't be. – Sam Feb 15 '18 at 17:25
  • Last question from me - Open your main app. Press home. Swipe to clear it from the recent apps. Does this immediately kill your Service? – brandall Feb 15 '18 at 17:37
  • @Sam I haven't been able to get my hands on another device, but from what users claim - service uptime is good. I might have to resort to hard resetting my device to know for sure. – farthVader Feb 15 '18 at 21:41
  • @KR_Android not feasible, app uses bluetooth services which just simply crash on an emulator. – farthVader Feb 15 '18 at 21:42
  • @brandall service stays up. I can see where you're going with this though(really appreciate the help), I have a simple log statement within `onTaskRemoved`. – farthVader Feb 15 '18 at 21:44
  • 2
    I had a just a simple log statement in `onTaskRemoved` before calling super. It prevented my foreground service from restarting on the Redmi Note 4. I could never explain it - I ended up not overriding it at all. I **wouldn't** suggest hard resetting your device - whatever issues you are having now, will be experienced in production by your users. You'll curse that you can no longer replicate the issue when the reports start to come in... I'm out of suggestions for now, but I strongly advise to hang in there & solve it! A complete memory dump from a full day's usage would be my next suggestion – brandall Feb 15 '18 at 22:22
  • @brandall noted. Also considering the possibility that this issue may be due to my device being subscribed to unstable Android builds. – farthVader Feb 15 '18 at 22:31
  • In my oneplus 3 there my ForegroundService was killed randomly. It turned out that there is a process called BgDetect on OnePlus, that kills services that it thinks consume too much resources. The solution was to **pin the app in the recent apps view**. – Sobvan Jun 13 '18 at 14:01
  • Pinning the app indeed does mitigate the termination, but the issue here is not with the underlying system marking a process as resource heavy(thereby terminating it), but rather with how the restarts are being processed for sticky services. – farthVader Jun 13 '18 at 15:12

3 Answers3

2

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.

Shift Delete
  • 1,015
  • 6
  • 13
0

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

Suricat
  • 131
  • 4
0

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
Allen Luce
  • 7,859
  • 3
  • 40
  • 53