四大組件之Server

**Service**

Service與Activity一樣,是Android的四大組件之一。Activity是看得見的,而Service則是看不見的。看得見的Activity一般承擔顯示界面、控制的功能,而Service則承擔后臺任務。而Service與線程的區(qū)別在于,Service是Android的四大組件之一,所以系統(tǒng)不會輕易將其殺死。服務可有其他應用組件啟動,而且即使用戶切換到其他應用,服務仍將在后臺繼續(xù)運行。此外,組件可以綁定到服務,以與之進行交互,甚至是執(zhí)行進程間通信(IPC)。例如,服務可以處理網絡事務、播放音樂、執(zhí)行文件I/O或與內容提供程序交互,而所有這一切均可在后臺進行。

服務基本上分為兩種形式運行:

-?啟動

當應用組件(如Activity)通過調用startService()啟動服務時,服務即處于“啟動”狀態(tài)。一旦啟動,服務即可在后臺無限期運行,即使啟動服務的組件已被銷毀也不受影響。已啟動的服務通常是執(zhí)行單一操作,而且不會將結果返回給調用方。例如,它可能通過網絡下載或上傳文件。操作完成后,服務會自行停止運行。

-?綁定

當應用組件通過bindService()綁定到服務時,服務即處于“綁定”狀態(tài)。綁定服務提供了一個客戶端-服務器接口,允許組件與服務進行交互、發(fā)送請求、獲取結果,甚至是利用進程間通信(IPC)跨進程執(zhí)行這些操作。僅當與另一個應用組件綁定時,綁定服務才會運行。多個組件可以同時綁定到該服務,但全部取消綁定后,該服務即會被銷毀。

##startService()

????1.啟動后,服務就和啟動它的組件沒關系

????2.如果服務被意外,隔段時間會自動重啟,隨著被殺死的次數增多,間隔時間越來越久

????3.生命周期方法在主線程調用

????4.服務要和子線程配合

????5.生命周期:onCreate()-->onStartCommand()--onDestroy();,如果重復啟動一個service,onCreate()方法不會再調用,直接onStartCommand()

如果Service還沒有運行,則android先調用onCreate()然后調用onStart();

如果Service已經運行,則只調用onStart(),所以一個Service的onStart方法可能會重復調用多次。?調用stopService的時候直接onDestroy,

如果是調用者自己直接退出而沒有調用stopService的話,Service會一直在后臺運行。

該Service的調用者再啟動起來后可以通過stopService關閉Service。

所以調用startService的生命周期為:onCreate --> onStart(可多次調用) --> onDestroy

對于bindService()綁定回調Service會經歷:

context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop

onBind將返回給客戶端一個IBind接口實例,IBind允許客戶端回調服務的方法,比如得到Service運行的狀態(tài)或其他操作。

這個時候把調用者(Context,例如Activity)會和Service綁定在一起,Context退出了,

Srevice就會調用onUnbind->onDestroy相應退出。

所以調用bindService的生命周期為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。

一但銷毀activity它就結束,如果按home把它放到后臺,那他就不退出。

在Service每一次的開啟關閉過程中,只有onStart可被多次調用(通過多次startService調用),其他onCreate,onBind,onUnbind,onDestory在一個生命周期中只能被調用一次。

Service 類兩種啟動方法:

1.?Context.startService():

在同一個應用任何地方調用 startService() 方法就能啟動 Service 了,然后系統(tǒng)會回調 Service 類的 onCreate() 以及 onStart() 方法。這樣啟動的 Service 會一直運行在后臺,直到 Context.stopService() 或者 selfStop() 方法被調用。

另外如果一個 Service 已經被啟動,其他代碼再試圖調用 startService() 方法,是不會執(zhí)行 onCreate() 的,但會重新執(zhí)行一次 onStart() 。

2.?Context.bindService()?:

將?Service 和調用 Service 的客戶類綁起來,如果調用這個客戶類被銷毀,Service 也會被銷毀。用這個方法的一個好處是,bindService() 方法執(zhí)行后 Service 會回調上邊提到的 onBind() 方發(fā),你可以從這里返回一個實現了 IBind 接口的類,在客戶端操作這個類就能和這個服務通信了,比如得到 Service 運行的狀態(tài)或其他操作。如果 Service 還沒有運行,使用這個方法啟動 Service 就會 onCreate() 方法而不會調用 onStart()。

** 2.工作中遇到的安卓下線程與服務的區(qū)別:**

????1.進程和服務的定義

????線程(thread):線程是程序運行的最小單元,是分配cpu的基本單位,本應用程序托管。

????服務(service);是android的一種機制,對應的service是運行在主線程上的,它是由系統(tǒng)進程托管。他們之間的通信類似于client和server,是一種輕量級的ipc通信,這種通信的載體是binder,它是在linux層交換信息的一種ipc;

1)在應用中,如果是長時間的在后臺運行,而且不需要交互的情況下,使用服務。

同樣是在后臺運行,不需要交互的情況下,如果只是完成某個任務,之后就不需要運行,而且可能是多個任務,需要長時間運行的情況下使用線程。

2)如果任務占用CPU時間多,資源大的情況下,要使用線程。

3)最優(yōu)的使用方法

????????????創(chuàng)建并啟動一個service,在Service里面創(chuàng)建、運行并控制該Thread(因為任何Activity都可以控制同一個Service,而系統(tǒng)只會創(chuàng)建一個對應的Service的實例)還有個辦法是使用IntentService,它里面自帶了子線程,使用它就不用創(chuàng)建新線程了。

但由于是單個的worker thread,所以任務需要排隊,不適合大多數的多任務情況。

最后可以把Service想象成一種消息服務,而你可以在任何有Context的地方調用Context.startservice、Context.stopservice、Context.bindService,Context.unbindService,來控制它,也可以在Service里注冊BroadcastReceiver,在其他地方通過發(fā)broadcast來控制它。

生命周期

1)startService生命周期

oncreate()------onStartCommand()-----onDestroy()

如果重復啟動一個服務,oncreate()只走一次,只調用onStartCommand()

2)bindService生命周期

oncreate()----onBind()----onUnBind()

綁定后跟組件生命周期綁定

3)混合啟動生命周期

1.先啟動后綁定

oncreate()---onStartCommand()----onBind()----onUnBind()

解綁后,不會走onDestroy()方法,因為startService還在使用這個服務

2.先綁定后啟動

oncreate()----onBind()----onStartCommand()----onUnBind()----onDestroy()

方法

使用intent跳轉

starteService()啟動服務

stopeService()停止服務

bindService()綁定服務,需要三個參數,第一個是intent,第二個參數為服務連接器ServiceConnection,第三個參數BIND_AUTO_CREATE

unBindService()解綁服務

通信

service---->Activity

在service中,寫一個內部類繼承Binder,在內部類寫一個方法,在onBind()方法返回我們得內部類。在Activity頁面,我們bindService()服務連接器回調中,在onServiceConnected強制轉換對應的service,調用服務方法

mConn = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

//服務連接成功之后的回調

//IBinder service,這個對象是要綁定的服務里面的onBind()的返回值

MyService.MyBinder binder = (MyService.MyBinder) service;

//這樣就可以調用到服務里面的方法

binder.call();

}

@Override

public void onServiceDisconnected(ComponentName name) {

//服務斷開連接的回調

}

};

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容