5

我有一個具有可變生命期的服務。它可能從5分鐘到2小時執行(例如)。所以我在尋找最好的方法來做到這一點,我的服務必須實現以下功能:在Android中執行服務的最佳方法

  • 發送(我的服務器)每5秒LAT-長和一些額外的信息(string的,boolean年代和int的)

我已經嘗試了‘正常’的服務,並試圖做這樣的事情來實現這一目標:

public class MyFiveSecondsService extends Service { 
    private Handler handler; 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      //here send my new data 
     } 
    }; 

    public void onCreate(){ 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(handler == null){ 
      handler = new Handler(); 
     } 

     handler.post(r); 

     return super.onStartCommand(intent, flags, startId); 
    } 
} 

其實是代碼的工作,但我得到了一些性能公關oblems這種做法,所以我試圖做這樣的事情:

public class SendUniquePositionIntentService extends IntentService { 

    public SendUniquePositionIntentService() { 
     super("co.bomboapp.Service.IntentService.SendUniquePositionIntentService"); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     //do the logic here 
    } 
} 

public class MyFiveSecondsService extends Service { 
    private Handler handler; 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      //call my SendUniquePositionIntentService here 
     } 
    }; 

    public void onCreate(){ 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(handler == null){ 
      handler = new Handler(); 
     } 

     handler.post(r); 

     return super.onStartCommand(intent, flags, startId); 
    } 
} 

而且這種方法都沒有奏效,我已經關閉應用程序的任何服務不停地運轉。因此,在開始嘗試實現這一目標之前,我需要一些方向,做這種「無限循環服務」並保持性能的最佳方法是什麼?

我使用Android 4.1作爲最小API和目標5.0 API。 我的測試設備是Nexus 5正在運行Android 6. 現在我正在使用parse.com作爲數據庫。

+0

服務被設計爲在您的活動被破壞後仍然運行。所以不要忘記在工作完成時停止服務 –

+0

它會在適當的時候自行停止,但無論如何,謝謝! – guisantogui

+0

爲什麼你不直接調用SendUniquePositionIntentService?我認爲用SendUniquePositionIntentService實現你的需求就足夠了。 – xxxzhi

回答

3

「我已經嘗試了‘正常’的服務......但我得到了一些性能問題」

默認情況下,服務的應用程序的主線程上運行,所以當你創建一個處理程序與

public int onStartCommand(Intent intent, int flags, int startId) { 
    if(handler == null){ 
     handler = new Handler(); 
    } 
    ... 
} 

該處理程序與主線程的Looper相關聯,並且所有消息和可運行子程序都會在線程中傳遞並稍後執行。這就是「性能問題」的原因。從documentation

請記住,如果你使用一個服務,它仍然在默認情況下,你的應用程序的主線程運行...

關於第二個方法和部分

「...當我關閉應用程序的任何服務保持運行」

你還沒有提到你是如何「關閉」應用程序,但我可以看到的是

public int onStartCommand(Intent intent, int flags, int startId) { 
    ... 
    return super.onStartCommand(intent, flags, startId); 
} 

這意味着如果系統殺死了服務,它將默認被重新創建。所以,如果「關閉」你的應用程序是指殺死它,下面的行動鏈發生:

  1. 系統再現MyFiveSecondsService
  2. onStartCommand()被稱爲與處理器職位可運行
  3. run()方法SendUniquePositionIntentService內啓動

onStartCommand()文檔:

默認實現調用onStart(Intent,int)並返回START_STICKY或START_STICKY_COMPATIBILITY。

注意,開始從另一個服務(如在你的情況開始從MyFiveSecondsServiceSendUniquePositionIntentService)是多餘的,除非你打算。

問題的最後一部分讓我感到困惑。一方面它不適合你,因爲「...任何服務保持運行」但另一方面,你想「做這個」無限循環服務「」 ...?

如果您只需要對這些信息發送的「字符串,布爾和整數」到服務器(沒有任何反饋,即啓動該服務的組件),我想這只是夠你使用IntentService。這是一個「開箱即用」的框架,它在後臺線程上工作(讓您避免凍結主線程),並在完成後自行停止。作爲一個例子,你可以使用IntentService的文檔 - 寫得很好。

另請注意,服務在被系統殺死後的行爲取決於onStartCommand()返回的標誌。例如。請使用START_NOT_STICKY在應用程序被終止後不重新創建服務,或使用START_REDELIVER_INTENT重新創建它,並重新使用最後的Intent

+0

我的意圖是同時使用服務和serveral intentServices服務保持「無限循環」,即使用戶關閉應用程序,而intentService有一個專門的線程來完成這項艱苦的工作。 – guisantogui

+1

@guisantogui爲什麼_「使用serveral intentServices」_?僅僅啓動一個'IntentService'並在其中運行多個線程是不夠的。 (請看[ThreadPoolExecutor](http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html)來管理線程)。在IntentService的onHandleIntent()中,你可以按照自己的想法將其工作做成「無限」。重要的是要確保服務在關閉應用程序後仍然存在,應用程序可以根據答案通過適當的標誌進行管理。 – Onik

+0

不錯,我會看看ThreadPoolExecutor! :) – guisantogui

相關問題