2012-05-18 121 views
7

在開發人員網站上閱讀了大多數關於Android服務的可用文檔,以及在這裏的計算器中,我仍然對在單獨任務中運行服務的幾個方面感到困惑。希望有人能把我放在正確的軌道上。如何在Android服務中啓動長時間運行的後臺任務

比方說,我們有繁瑣的業務框架,如

public class HliService extends Service { 

    @Override 
    public void onCreate() { 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // If we get killed, after returning from here, restart 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // We don't provide binding, so return null 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
    } 
} 

,並在清單中,我有

<service android:name=".HliService" android:process=":HLI_Comms"/> 

,這樣服務在自己的線程中運行。

該服務的目的是提供一個後臺任務,將 與使用TCP套接字的設備進行通信並執行其他操作。在忽略電池問題等風險,基本上我希望它永遠運行。

喜歡的東西

// Method that communicates using a TCP socket, and needs to send 
// information back to the activity and receive messages from activity 
// not shown here. 
private void dummytask() { 

    boolean keepGoing = true; 
    while (keepGoing) { 
     // do useful stuff in here 
     // sets keepGoing false at some point 
    } 
    stopSelf(); 
} 

什麼是發起這種方法/任務的最佳方法是什麼?

我看過使用消息處理程序和活套的開發人員站點中的代碼,我只能部分理解,但它看起來非常複雜,可能比我需要的更多?

我不相信我可以從onCreate()onStartCommand()調用此方法,因爲從系統調用時都不會完成?我應該用計時器還是鬧鐘啓動它?

我需要添加一個消息處理程序來與gui活動進行通信,但由於我在另一個線程中啓動服務(憑藉清單「process」指令),是否需要使用AIDL ?

我也看過使用AysnchTask而不是擴展Service,但它似乎更適合運行任務,然後終止。

+0

'while(keepGoing)' - 如果這是另一個線程,而不是將keep_inging設置爲false的線程'keepGoing'必須是'volatile' - 在Java內存模型上讀取 –

+0

請參閱此答案可能幫助您。 [此處輸入鏈接的描述] [1] [1]:http://stackoverflow.com/a/13783477/2165080 –

回答

2

使服務運行在它自己的線程中。

這使服務在其自己的進程。這通常是需要避免的,因爲它消耗額外的RAM和CPU(用於IPC)。您可以創建一個線程,只需創建Thread或任意數量的其他方法,其中大部分已經在Java中使用了十年左右。

在忽略電池問題等風險,基本上我希望它永遠運行。

服務永遠不可能運行。用戶或操作系統最終會擺脫您的服務。

啓動此方法/任務的最佳方法是什麼?

從後臺線程調用dummytask()

我需要使用AIDL嗎?

。您的服務可以播放一個Intent,或調用由該活動提供的PendingIntent,也可以通過活動等的最佳提供的Messenger發送Message將是從Android支持使用LocalBroadcastManager包,但這不會跨越流程邊界,迫使您進入更昂貴的通信選項。

+0

確定 - 感謝@CommonsWare。我也研究過這種方法,但我也不確定實施它的某些方面 - 我會做更多的研究,並可能會發布後續問題。我會就不使用「流程」提出建議。順便說一句,我知道這項服務實際上不會永遠運行 - 這只是一種簡化。再次感謝。 – SteveJP

+0

@CommonsWare感謝上面的解釋......真的很好 – Biplab

0

我認爲你可以使用IntentService,你可以通過設置一個(常規)鬧鐘(AlarmManager.setRepeating)和PendingIntent來運行它。您可以通過從IntentService廣播Intent並通過BroadcastReceiver在您的用戶界面中接收它來通知UI。

+0

謝謝@omoling - 這不是更適合於只運行一個小任務,然後終止,而是啓動一個長期運行的過程? – SteveJP

相關問題