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


    分析基于Android8.0。

    【操作步骤】

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

    【结果】

               音乐播放异常

    【原因】

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

    log中包含如下信息:

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

    【分析】
    以上log来自ActiveServices.stopInBackgroundLocked函数:

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

    1. (181101_10:29:01.984)01-01 00:09:19.735   448   533 D ActiveServices: stopInBackgroundLocked
    2. (181101_10:29:01.994)01-01 00:09:19.736   448   533 D ActiveServices: java.lang.Throwable
    3. (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)
    4. (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)
    5. (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)
    6. (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)
    7. (181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices:     at android.os.Handler.dispatchMessage(Handler.java:106)
    8. (181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices:     at android.os.Looper.loop(Looper.java:164)
    9. (181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices:     at android.os.HandlerThread.run(HandlerThread.java:65)
    10. (181101_10:29:01.995)01-01 00:09:19.736   448   533 D ActiveServices:     at com.android.server.ServiceThread.run(ServiceThread.java:46)
    11. (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
  • 相关阅读:
    Axure学习记录(菜单下拉/收起效果)
    redis-cli客户端中获取数据中文显示xe问题
    QString格式化
    15 检验的优良性
    DDPG算法
    Spark在大数据集群下的部署
    中间件漏洞 | Apache-路径穿越/任意命令执行
    nginx动态新增模块
    学习笔记20--汽车运动控制
    洛谷 P1028 [NOIP2001 普及组] 数的计算
  • 原文地址:https://blog.csdn.net/liuqinhou/article/details/126212064