Android 服务的线程调度问题
Thread scheduling issue with Android service
我有一个驱动程序 (Android HAL) 和一个通过 unix 套接字相互通信的服务。他们都有一个线程来使用心跳来维持连接。 HAL 是套接字守护进程,服务是套接字客户端。
HAL 在启动时加载。当应用程序绑定到服务时加载服务。此应用不会执行任何其他操作。
我观察到只要App可见,客户端线程和守护线程都可以。但是当我将应用程序推到后台时(例如,通过按主页按钮),我观察到守护线程报告的客户端线程中的一堆超时(因为发送心跳的速度不够快)。
我做了一些计时测量,发现只要应用程序可见,服务就会正常运行,但是当应用程序不可见时,服务线程就会运行不稳定。就好像调度程序没有足够频繁地执行服务中的线程。
此时Android系统上没有其他应用。
此行为已通过 Nexus 7 (2013) 和 Nexus 5X 运行ning M 和 Nexus Player 运行ning Android N
验证
如果应用程序启动服务,而不是绑定到它,错误的线程调度仍然存在。唯一不同的是,现在 App 可见性状态不会影响服务线程执行(它总是很慢。)
有没有办法让服务线程 运行 更快?
主要是,线程只是执行一个 select() 调用 10 毫秒,然后在循环中进行一些簿记。伪代码如下:
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:
也许有必要提一下,在最终系统中,我需要能够在启动时提供 "start" 服务,并且不应有任何应用程序。在这种情况下,我需要服务线程才能正确执行。
编辑 2:
发现如果我将我的服务设置为 "foreground service",这个调度问题就会平息。
令我感到困惑的是,服务进程的优先级不足以使其执行得足够频繁,即使在 cpu 负载较低的情况下也是如此。理想情况下,我不需要这样做。
暂时保留问题,以防出现有用的答案。
只要我需要我的服务及时执行,我就会创建并保留一个通知图标。
这对 phone/tablet 版本和 Android 电视版本都有帮助,即使电视不显示通知图标。从通知中删除图标后,服务变慢。
后来我想了想,意识到可能没有服务需要及时做后台任务,但也没有通知icon/controls。例如。在后台播放的音乐播放器通常会在通知中留下控件。
如果有人找到更好的解决方案,请公开。
我有一个驱动程序 (Android HAL) 和一个通过 unix 套接字相互通信的服务。他们都有一个线程来使用心跳来维持连接。 HAL 是套接字守护进程,服务是套接字客户端。
HAL 在启动时加载。当应用程序绑定到服务时加载服务。此应用不会执行任何其他操作。
我观察到只要App可见,客户端线程和守护线程都可以。但是当我将应用程序推到后台时(例如,通过按主页按钮),我观察到守护线程报告的客户端线程中的一堆超时(因为发送心跳的速度不够快)。
我做了一些计时测量,发现只要应用程序可见,服务就会正常运行,但是当应用程序不可见时,服务线程就会运行不稳定。就好像调度程序没有足够频繁地执行服务中的线程。
此时Android系统上没有其他应用。
此行为已通过 Nexus 7 (2013) 和 Nexus 5X 运行ning M 和 Nexus Player 运行ning Android N
验证如果应用程序启动服务,而不是绑定到它,错误的线程调度仍然存在。唯一不同的是,现在 App 可见性状态不会影响服务线程执行(它总是很慢。)
有没有办法让服务线程 运行 更快?
主要是,线程只是执行一个 select() 调用 10 毫秒,然后在循环中进行一些簿记。伪代码如下:
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: 也许有必要提一下,在最终系统中,我需要能够在启动时提供 "start" 服务,并且不应有任何应用程序。在这种情况下,我需要服务线程才能正确执行。
编辑 2: 发现如果我将我的服务设置为 "foreground service",这个调度问题就会平息。
令我感到困惑的是,服务进程的优先级不足以使其执行得足够频繁,即使在 cpu 负载较低的情况下也是如此。理想情况下,我不需要这样做。
暂时保留问题,以防出现有用的答案。
只要我需要我的服务及时执行,我就会创建并保留一个通知图标。
这对 phone/tablet 版本和 Android 电视版本都有帮助,即使电视不显示通知图标。从通知中删除图标后,服务变慢。
后来我想了想,意识到可能没有服务需要及时做后台任务,但也没有通知icon/controls。例如。在后台播放的音乐播放器通常会在通知中留下控件。
如果有人找到更好的解决方案,请公开。