2016-12-29 88 views
1

我有一個驅動程序(Android HAL)和一個通過unix套接字相互通信的服務。他們都有一個線程來保持連接使用心跳。 HAL是套接字守護進程,服務是套接字客戶端。Android服務的線程調度問題

HAL在啓動時加載。服務在應用程序綁定時加載。這個應用程序不會做任何事情。

我注意到,只要應用程序可見,客戶端和守護程序線程都可以。但是當我將應用程序推到後臺時(例如通過按回家鍵),我觀察到由守護線程報告的客戶端線程中有一堆超時(因爲心跳發送不夠快)。

我做了一些時間測量,發現只要應用程序可見,服務的行爲是正確的,但是當應用程序不可見時,服務線程表現不正常。這幾乎就像調度程序不經常在服務中執行線程一樣。

目前,Android系統上沒有其他應用程序。

此行爲不符合的Nexus 7(2013)和Nexus 5X運行M和Nexus Player遊戲運行Androidň

如果應用程序啓動的服務,而不是綁定到它驗證,壞線程調度仍然存在。唯一不同的是,現在應用程序可見性狀態不影響服務線程執行(它總是很慢)。

有沒有辦法讓服務線程運行得更快?

主要是,線程只是做一個select()調用10ms,然後循環一些書籍。僞代碼如下:

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: 也許是必要提一下,在最終的系統,我需要能夠在啓動「開始」的服務,並不得有應用。在這種情況下,我需要Service線程才能正確執行。

編輯2: 發現如果我讓我的服務成爲「前臺服務」,這個調度問題就會消退。

我很困惑,一個服務進程的優先級不足以讓它足夠頻繁地執行,即使在CPU負載很低的情況下也是如此。理想情況下,我不應該這樣做。

暫時保留問題,以防萬一有用的答案彈出。

+0

除非啓動服務屬於用戶至少啓動一次的應用程序,否則無法啓動服務。看[這個答案](http://stackoverflow.com/a/30112243/1953590)。 –

+0

@Kevin:對於從遊戲商店或其他地方「安裝」的東西,這是真的。這些將是系統服務/應用程序。順便說一句,作爲系統服務安裝它們並不能解決這個問題。 – GPS

回答

0

只要我需要我的服務及時執行,我就會創建並保留一個通知圖標。

即使電視沒有顯示通知圖標,這對手機/平板電腦版本和Android TV版本都有幫助。當圖標從通知中刪除時,服務變慢。

我後來想到了這一點,並意識到可能沒有服務需要及時做後臺任務,但也沒有通知圖標/控件。例如。在後臺播放的音樂播放器通常會將控制權留在通知中。

如果有人找到更好的解決方案,請將其展開。