xingda920813 / HelloDaemon

Android 服务保活/常驻 (Android service daemon using JobScheduler)
MIT License
2.31k stars 443 forks source link

Android 7.1 , if we clear the app from recent tasks it restarts the service? is it normal? #6

Closed mianharisali closed 7 years ago

xingda920813 commented 7 years ago

Android 7.1 fixed the bug which an App can bring a service to foreground without showing a notification. So, to avoid bad user experience, in Android 7.1 we do not use foreground service, so no notifications will be shown. But leave services background brings a side effort, it is when you slide the app's card from recent tasks, the app's process is actually killed (if you use Android Studio's Monitor, you can see com.xdandroid.HelloDaemon(DEAD) appears shortly), and then, because we return Service.START_STICKY in Service.onStartCommand(), Android restartes the service automatically. So this is normal when we do not have a good approach to use foreground services without showing notifications.

Sample in this repo is not very powerful. If you have strong demand on service daemon, I recommend using Marswin / MarsDaemon (https://github.com/Marswin/MarsDaemon), which can make your App undead below Marshmallow.

pinkApple commented 7 years ago

国产rom, 华为,还有其他rom上测试, 前台服务即使是空也显示了一个服务正在运行的前台通知.

mianharisali commented 7 years ago

@xingda920813 thanks for explaining it . but sometimes it takes a long time to restart the service , there was a solution to restart it immediately. that was in service onTaskRemoved method we start a dummy activity with no view. it restarts it immediately. can you tell me is it good way to do that.?

pinkApple commented 7 years ago

@mianharisali it's strange the author removed the code your described. at the early version in job service, onStart, onEnd method exists.

mianharisali commented 7 years ago

@pinkApple i did not provided any source code. what source you are talking about?

xingda920813 commented 7 years ago

@pinkApple

1.I used remote device rent service provided in Tencent U-Test platform to test the sample's behaviour.

Huawei Mate 9 (Android 7.0), Huawei Honor 8 (Android 6.0), Huawei Mate 7 (Android 4.4), Xiaomi MI 4 (Android 6.0), Xiaomi Redmi 1S (Android 4.4) didn't show a notification after starting service. These daemon methods are for our production use, and we did not ever find notifications show up.

If you directly use this sample, what device and what Android version did you test on?

If you migrate these configs to your project, make sure the Manifest entries are complete and right, escpecially check for 2 *NotificationService inner class entries.

2.onEnd(), onTaskRemoved(), onStopJob() in JobSchedulerService are removed because it will prevent the job being cancelled when we don't need it. When you call JobScheduler.cancel(int jobId), onStopJob() is called. If in onStopJob() we pull up services again, then how can we stop the job and the service when we don't need them?

Besides, these methods are useless for the daemon of our service. JobScheduler will call onStartJob() periodly (have set in JobInfo) even when package stopped, and in onStartJob(), we pull up our services. OnStopJob() or onTaskRemoved() will not be called.

xingda920813 commented 7 years ago

@mianharisali

1.I didn't see a lag in restarting services. After I clear the app, the app will be shortly dead and then respawn in seconds. If it did not respawn shortly, that's possible limitations of customed ROMs. I am on Cyanogenmod 14.1 (Android 7.1.1), what device and Android version do you test on? I will try to reproduce the issue.

2.That has been used in many apps. It's implemented in section 3.1 of this article: http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8

I doubt about the solution. Have you tested its effectiveness? I think both starting a service and starting an activity are IPC opertions, and should not make a huge difference. But I will do a test on this method.

Update: The 2 methods showed no difference for Huawei and Xiaomi devices, both can not restart. For CyanogenMod, both 2 methods can restart service.

pinkApple commented 7 years ago

@xingda920813 I'm glad for your patient reply, but some problems confuse me a lot. what's the main purpose to cancelled the job or service when don't need? Any methods you do is to keep the app alive. the case in whitelist? so if in the whitelist, how did you know the user is in whitelist? the battery optimises flag only get in 6.0 and later.

xingda920813 commented 7 years ago

@pinkApple

  1. For longer battery life. When we don't have tasks to do, we possibly don't want to start the service PERIODLY.

  2. There seems to be no way. The author of custom ROMs did not privide such an API to let us know if we are already in the white list. Some article mentioned a little, but it is really a bit tricky.

  3. Below Marshmallow, there is no Doze mode. In Marshmallow, Doze mode is very hard to enter. Nougat introduced "Doze on the go", which can let device enter Doze mode even when you are walking, having your device in pocket. So we only process battery optimization above Nougat.

xingda920813 commented 7 years ago

Please proceed to new issue to further discuss. Thank you!