6

創建一個作爲單例使用的Service是不好的做法嗎?我的意思是Service是從來沒有停止過,幷包含一些其他的引擎和Activities會使用一些私人數據,所以Service可能有類似:在Android中使用服務作爲單例

public class CustomService extends Service { 
    private List<Profile> mProfiles; 
    private static CustomService instance; 

    public static CustomService getInstance() { 
     if(instance == null) { 
      instance = new CustomService(); 
     } 
     return instance; 
    } 

    public List<Profile> getProfiles() { 
      return mProfiles; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     ... 
    } 
    ... 
} 

Service,而不是僅僅一個單例的原因它必須獨立於應用程序工作,因爲它在啓動時連接一個永遠不應該關閉並且不依賴於應用程序的websocket。你會建議我做什麼?有沒有更好的方法來重新使用Service以便從其他引擎獲得一些數據(例如mProfiles陣列)和Activities

我讀過某個地方Service作爲一個單身人士,但我不知道如何從應用程序的任何其他點訪問私有變量。

在此先感謝。

+0

據我所知,你不應該自己創建一個服務實例,而應該使用'startService()'使用上下文。我不確定使用'new CustomService();' –

+0

會帶來什麼後果?嗨,謝謝你的回答。但startService將啓動該服務並調用onStartCommand,但這不是我想要的。我想在應用程序的onCreate方法上啓動一次服務,然後從應用程序的任何其他位置獲取服務的私有變量 – FVod

回答

7

創建一個作爲單例服務的服務是不好的做法嗎?

這是多餘的,在你建議的方式,不會從視圖中AndroidService作爲應用程序組件這是相對於執行其功能

  • Application生命週期點的工作, ,反過來,受到系統事件影響的

這種由

  • 其聲明在AndroidManifest.xml
  • 達到一個應用程序組件的意圖觸發它(起始/結合/登記)和
  • 創建(由系統) Application中的組件實例,並將其「附加」到ApplicationThread/ActivityThread

也就是說,帶來了一個事實,即應用程序組件依賴於通過操作系統進程和主辦不能獨立運行Application實例。


關於你的方法,有兩種情況

CustomService的默認構造函數是私有按格局。

致電getInstance()創建了一個CustomService的實例。實例只是一個Java對象(單例),它與AndroidService應用程序組件沒有任何共同之處。系統不會調用onStart(),onStartCommand()等方法。

嘗試使用startService(Intent)啓動「服務」(在清單中聲明)將失敗,並顯示IllegalAccessException: access to constructor not allowed

2.CustomService的默認構造是公(根據發佈的代碼)。

如果該服務被AndroidManifest聲明,默認的構造函數是空的,startService()不會失敗,但是getInstance()將創造CustomService另一個實例,將不會被視爲AndroidService應用程序組件。

這不是一個單身人士。


什麼你會建議我做什麼?有沒有更好的方式來重新使用服務,以便從其他引擎和活動獲得一些數據(例如mProfiles數組)?

使用Servicethe documentation和挑那種通信的需要:

  • 單向通信(Activity-->Service) - 使用started Service和處理每個Intent(與連接到它的數據,如mProfiles(如果Profile類實施ParcelableonStartCommand();
  • 雙向通信(Activity<->Service) - 使用bound Service並通過IBinder進行通信。

最後,ServiceAndroid是一個單身人士。系統中每個服務只有一個實例。它按需啓動並處理所有待定的Intent s/bound客戶端。一旦完成或明確停止,它將被銷燬。

+0

非常感謝您的回答。但是,有沒有辦法從引擎獲取服務的私有變量?我讀過只有活動或服務可以綁定到服務,所以我怎麼能從廣播接收器或從另一個單例或引擎獲取mProfiles數組(例如)?非常感謝。 – FVod

+0

我不知道你是什麼意思的「引擎」,但如果你有[''Context'](http://developer.android.com/reference/android/content/Context.html)在你的處置,你可以開始/綁定到服務。綁定後,您可以通過[IBinder](http://developer.android.com/reference/android/os/IBinder.html)發送任何實現Parcelable的數據,包括IPC。如果你周圍沒有上下文,那麼你可以做的事情就不多了(儘管我不知道你的用例)......我最好的建議是閱讀官方文檔(它很適合Android),在那裏,特別是您可以在活動 - 服務交流中找到一個例子。 – Onik

0

它創建一個服務作爲一個singleton.You可以開始你的服務粘滯,你可以通過它的名字檢索你的服務,並檢查它是否工作與活動內的下面的代碼。

private boolean isMyServiceRunning(Class<?> serviceClass) { 
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
    if (serviceClass.getName().equals(service.service.getClassName())) { 
     return true; 
    } 
} 
return false; 

}

0

如果(我還沒有找到的文件來支持這一點,但假設它的話)服務由Android框架實例化只有一次,那麼你可以初始化instanceService.onCreate。唯一的缺點是,如果你沒有保證,這將被稱爲。也就是說,如果你在Application.onCreate之內調用startService,那麼在你的服務真正實例化之前,你很可能不得不等待一下。