Android之startService与bindService的区别
Android執行Service有兩種方法,一種是startService,一種是bindService。下面讓我們一起來聊一聊這兩種執行Service方法的區別。
1、生命周期上的區別
????執行startService時,Service會經歷onCreate->onStartCommand。當執行stopService時,直接調用onDestroy方法。調用者如果沒有stopService,Service會一直在后臺運行,下次調用者再起來仍然可以stopService。
????執行bindService時,Service會經歷onCreate->onBind。這個時候調用者和Service綁定在一起。調用者調用unbindService方法或者調用者Context不存在了(如Activity被finish了),Service就會調用onUnbind->onDestroy。這里所謂的綁定在一起就是說兩者共存亡了。
????多次調用startService,該Service只能被創建一次,即該Service的onCreate方法只會被調用一次。但是每次調用startService,onStartCommand方法都會被調用。Service的onStart方法在API 5時被廢棄,替代它的是onStartCommand方法。
????第一次執行bindService時,onCreate和onBind方法會被調用,但是多次執行bindService時,onCreate和onBind方法并不會被多次調用,即并不會多次創建服務和綁定服務。
2、調用者如何獲取綁定后的Service的方法
????onBind回調方法將返回給客戶端一個IBinder接口實例,IBinder允許客戶端回調服務的方法,比如得到Service運行的狀態或其他操作。我們需要IBinder對象返回具體的Service對象才能操作,所以說具體的Service對象必須首先實現Binder對象。
3、既使用startService又使用bindService的情況
????如果一個Service又被啟動又被綁定,則該Service會一直在后臺運行。首先不管如何調用,onCreate始終只會調用一次。對應startService調用多少次,Service的onStart方法便會調用多少次。Service的終止,需要unbindService和stopService同時調用才行。不管startService與bindService的調用順序,如果先調用unbindService,此時服務不會自動終止,再調用stopService之后,服務才會終止;如果先調用stopService,此時服務也不會終止,而再調用unbindService或者之前調用bindService的Context不存在了(如Activity被finish的時候)之后,服務才會自動停止。
????那么,什么情況下既使用startService,又使用bindService呢?
????如果你只是想要啟動一個后臺服務長期進行某項任務,那么使用startService便可以了。如果你還想要與正在運行的Service取得聯系,那么有兩種方法:一種是使用broadcast,另一種是使用bindService。前者的缺點是如果交流較為頻繁,容易造成性能上的問題,而后者則沒有這些問題。因此,這種情況就需要startService和bindService一起使用了。
????另外,如果你的服務只是公開一個遠程接口,供連接上的客戶端(Android的Service是C/S架構)遠程調用執行方法,這個時候你可以不讓服務一開始就運行,而只是bindService,這樣在第一次bindService的時候才會創建服務的實例運行它,這會節約很多系統資源,特別是如果你的服務是遠程服務,那么效果會越明顯(當然在Servcie創建的是偶會花去一定時間,這點需要注意)。? ??
4、本地服務與遠程服務
????本地服務依附在主進程上,在一定程度上節約了資源。本地服務因為是在同一進程,因此不需要IPC,也不需要AIDL。相應bindService會方便很多。缺點是主進程被kill后,服務變會終止。
????遠程服務是獨立的進程,對應進程名格式為所在包名加上你指定的android:process字符串。由于是獨立的進程,因此在Activity所在進程被kill的是偶,該服務依然在運行。缺點是該服務是獨立的進程,會占用一定資源,并且使用AIDL進行IPC稍微麻煩一點。
????對于startService來說,不管是本地服務還是遠程服務,我們需要做的工作都一樣簡單。
5、代碼實例
????startService啟動服務
public class LocalService1 extends Service {/*** onBind 是 Service 的虛方法,因此我們不得不實現它。* 返回 null,表示客服端不能建立到此服務的連接。*/@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onStartCommand(Intent intent, int startId, int flags) {super.onStartCommand(intent, startId, flags);}@Overridepublic void onDestroy() {super.onDestroy();} }?bindService綁定服務 public class LocalService extends Service { /** * 在 Local Service 中我們直接繼承 Binder 而不是 IBinder,因為 Binder 實現了 IBinder 接口,這樣我們可以** 少做很多工作。 */ public class SimpleBinder extends Binder{ /** * 獲取 Service 實例 * @return */ public LocalService getService(){ return LocalService.this; }public int add(int a, int b){ return a + b; } }public SimpleBinder sBinder;@Override public void onCreate() { super.onCreate(); // 創建 SimpleBinder sBinder = new SimpleBinder(); }@Override public IBinder onBind(Intent intent) { // 返回 SimpleBinder 對象 return sBinder; } }
? 上面的代碼關鍵之處,在于 onBind(Intent) 這個方法 返回了一個實現了 IBinder?接口的對象,這個對象將用于綁定Service 的 Activity 與 Local Service 通信。
????下面是 Activity 中的代碼:
public class Main extends Activity {private final static String TAG = "SERVICE_TEST";private ServiceConnection sc;private boolean isBind;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);sc = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {LocalService.SimpleBinder sBinder = (LocalService.SimpleBinder)service;Log.v(TAG, "3 + 5 = " + sBinder.add(3, 5));Log.v(TAG, sBinder.getService().toString());}};findViewById(R.id.btnBind).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {bindService(new Intent(Main.this, LocalService.class), sc, Context.BIND_AUTO_CREATE);isBind = true;}});findViewById(R.id.btnUnbind).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(isBind){unbindService(sc);isBind = false;}}});} }6、在AndroidManifest.xml里Service元素常見選項 ?
????android:name ------------- 服務類名
????android:label -------------- 服務的名字,如果此項不設置,那么默認顯示的服務名則為類名
????android:icon -------------- 服務的圖標
????android:permission ------- 申明此服務的權限,這意味著只有提供了該權限的應用才能控制或連接此服務
????android:process ---------- 表示該服務是否運行在另外一個進程,如果設置了此項,那么將會在包名后面加上這段字符串表示另一進程的名字
????android:enabled ---------- 表示是否能被系統實例化,為true表示可以,為false表示不可以,默認為true
????android:exported --------- 表示該服務是否能夠被其他應用程序所控制或連接,不設置默認此項為 false
總結
以上是生活随笔為你收集整理的Android之startService与bindService的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之Toolbar的三个问题
- 下一篇: Android之AudioManager