【问题标题】:Thread scheduling issue with Android serviceAndroid服务的线程调度问题
【发布时间】:2016-12-29 09:08:47
【问题描述】:

我有一个驱动程序 (Android HAL) 和一个通过 unix 套接字相互通信的服务。他们都有一个线程来使用心跳保持连接。 HAL 是套接字守护进程,服务是套接字客户端。

HAL 在启动时加载。当应用程序绑定到它时加载服务。此应用不执行任何其他操作。

我观察到,只要 App 可见,客户端和守护线程都可以。但是当我将应用程序推到后台时(例如,通过按下主页按钮),我观察到守护线程报告的客户端线程中的一堆超时(因为心跳发送速度不够快)。

我做了一些计时测量,发现只要应用程序可见,Service 就会正常运行,但是当应用程序不可见时,服务线程就会出现异常行为。这几乎就像调度程序没有足够频繁地执行服务中的线程一样。

此时,Android系统上没有其他应用。

此行为已通过运行 M 的 Nexus 7 (2013) 和 Nexus 5X 以及运行 Android N 的 Nexus Player 验证

如果应用程序启动服务,而不是绑定到它,错误的线程调度仍然存在。唯一不同的是,现在 App 可见性状态不会影响服务线程的执行(它总是很慢。)

有没有办法让服务线程运行得更快?

主要是,线程只执行 10 毫秒的 select() 调用,然后在循环中进行一些记账。伪代码如下:

while(running) {
    if not_connected {
        connect()
    }
    if send_heartbeat_timeout_elapsed
        send_heartbeat()
    }
    if recv_heartbeat_timeout_elapsed {
        close_connection()
    }
    if connected {
        wait_for_daemon_msg(10 ms) 
        if msg_received {
            process_msg()
        }
    }
}

编辑 1: 也许值得一提的是,在最终系统中,我需要能够在启动时“启动”服务,并且应该没有应用程序。我需要服务线程在这种情况下正确执行。

编辑 2: 发现如果我让我的服务成为“前台服务”,这个调度问题就会消退。

令我感到困惑的是,服务进程的优先级不足以让它足够频繁地执行,即使在 CPU 负载较低的情况下也是如此。理想情况下,我不需要这样做。

暂时保留问题,以防出现有用的答案。

【问题讨论】:

  • 您不能在启动时启动服务,除非它属于用户至少启动过一次的应用程序。见this answer
  • @Kevin:对于您从 Play 商店或其他地方“安装”的东西来说确实如此。这些将是系统服务/应用程序。顺便说一句,将它们安装为系统服务并不能解决这个问题。

标签: android multithreading service scheduler


【解决方案1】:

只要我需要我的服务及时执行,我就会创建并保留一个通知图标。

这对手机/平板电脑版本和 Android TV 版本都有帮助,即使 TV 不显示通知图标。当图标从通知中移除时,服务会变慢。

后来我想到了这一点,意识到可能没有服务需要及时执行后台任务,但也没有通知图标/控件。例如。在后台播放的音乐播放器通常会将控件留在通知中。

如果有人找到更好的解决方案,请提出来。

【讨论】:

    猜你喜欢
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    相关资源
    最近更新 更多