startService启动服务,应用置于后台超过1min,服务被销毁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011386173/article/details/83615924

分析基于Android8.0。

【操作步骤】

  1. 播放音乐
  2. 音乐切到后台,播放其他音源超过1min
  3. 再将音乐切到前台

【结果】

   音乐播放异常

【原因】

   应用在后台空闲超过1min,系统销毁了服务。

   log中包含如下信息:

ActivityManager: Stopping service due to app idle: u0a60 -1m14s699ms com.example.maureen.mytestbindservice/.TestRemoteService

【分析】

以上log来自ActiveServices.stopInBackgroundLocked函数:

而该函数因为应用处于后台空闲而被调用的堆栈信息:

(181101_10:29:01.984)01-01 00:09:19.735   448   533 D ActiveServices: stopInBackgroundLocked
(181101_10:29:01.994)01-01 00:09:19.736   448   533 D ActiveServices: java.lang.Throwable
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at com.android.server.am.ActiveServices.stopInBackgroundLocked(ActiveServices.java:621)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at com.android.server.am.ActivityManagerService.doStopUidLocked(ActivityManagerService.java:23605)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at com.android.server.am.ActivityManagerService.idleUids(ActivityManagerService.java:23464)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at com.android.server.am.ActivityManagerService$MainHandler.handleMessage(ActivityManagerService.java:2443)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at android.os.Handler.dispatchMessage(Handler.java:106)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at android.os.Looper.loop(Looper.java:164)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at android.os.HandlerThread.run(HandlerThread.java:65)
(181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices: 	at com.android.server.ServiceThread.run(ServiceThread.java:46)
(181101_10:29:01.995)01-01 00:09:19.737   448   533 W ActivityManager: Stopping service due to app idle: u0a59 -1m49s392ms com.example.maureen.mytestbindservice/.TestRemoteService

因为添加了部分log信息,所以与源码的代码行数不对应。其中ActivityManagerService.java的2443行对应的就是:

而IDLE_UIDS_MSG消息来源于AMS.idleUids或AMS.updateOomAdjLocked函数:

updateOomAdjLocked函数:

可以看到都是通过发送延时消息来停止服务的。而这个延时时间BACKGROUND_SETTLE_TIME的值:

ActivityManagerConstants.java

就是60s,即1min。

也就是说在后台超过1min,IDLE_UIDS_MSG就会执行,也就会将服务销毁。

【解决方案】

启动前台服务。

  • 调用startForegroundService启动服务
  • 在服务的onStartCommand中调用startForeground (5s内调用,否则会导致ANR),并设置Nofitication

猜你喜欢

转载自blog.csdn.net/u011386173/article/details/83615924