概述:
Service(服務(wù))是一個(gè)一種可以在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而沒有用戶界面的應(yīng)用組件。服務(wù)可由其他應(yīng)用組件啟動(dòng)(如Activity)所森,服務(wù)一旦被啟動(dòng)將在后臺(tái)一直運(yùn)行加矛,即使啟動(dòng)服務(wù)的組件(Activity)已銷毀也不受影響塞耕。
(1)不同點(diǎn):
Activity : 可以和用戶交互, 頁面可見。
Service : 后臺(tái)運(yùn)行, 沒有界面程癌。
(2)相同點(diǎn):
在清單文件中注冊(cè), 都有自己的生命周期舷嗡。
此外,組件可以綁定到服務(wù)嵌莉,以與之進(jìn)行交互进萄,甚至是執(zhí)行進(jìn)程間通信 (IPC)。 例如锐峭,服務(wù)可以處理網(wǎng)絡(luò)事務(wù)中鼠、播放音樂,執(zhí)行文件 I/O 或與內(nèi)容提供程序交互沿癞,而所有這一切均可在后臺(tái)進(jìn)行援雇,Service基本上分為兩種形式:
startService
bindService
Service特點(diǎn):
service在后臺(tái)運(yùn)行,不用與用戶進(jìn)行交互椎扬。即使應(yīng)用退出惫搏,服務(wù)也不會(huì)停止。
當(dāng)應(yīng)用進(jìn)程被殺死時(shí)蚕涤,服務(wù)便會(huì)停筐赔。
service運(yùn)行在主線程中,當(dāng)需要執(zhí)行耗時(shí)操作的時(shí)候揖铜,需要在服務(wù)中創(chuàng)建子線程完成茴丰。
service 的用途:播放音樂、后臺(tái)下載大文件等天吓。
Service的啟動(dòng)方式以及生命周期
onCreate():
首次創(chuàng)建服務(wù)時(shí)贿肩,系統(tǒng)將調(diào)用此方法。如果服務(wù)已在運(yùn)行龄寞,則不會(huì)調(diào)用此方法尸曼,該方法只調(diào)用一次。
onStartCommand():
當(dāng)另一個(gè)組件(如 Activity)通過調(diào)用 startService() 請(qǐng)求啟動(dòng)服務(wù)時(shí)萄焦,系統(tǒng)將調(diào)用此方法。一旦執(zhí)行此方法,服務(wù)即會(huì)啟動(dòng)并可在后臺(tái)無限期運(yùn)行拂封。 如果自己實(shí)現(xiàn)此方法茬射,則需要在服務(wù)工作完成后,通過調(diào)用 stopSelf() 或 stopService() 來停止服務(wù)冒签。(在綁定狀態(tài)下在抛,無需實(shí)現(xiàn)此方法。)
onDestroy():
當(dāng)服務(wù)不再使用且將被銷毀時(shí)萧恕,系統(tǒng)將調(diào)用此方法刚梭。服務(wù)應(yīng)該實(shí)現(xiàn)此方法來清理所有資源,如線程票唆、注冊(cè)的偵聽器朴读、接收器等,這是服務(wù)接收的最后一個(gè)調(diào)用走趋。
onBind():
當(dāng)另一個(gè)組件想通過調(diào)用 bindService() 與服務(wù)綁定衅金,系統(tǒng)將調(diào)用此方法。在此方法的實(shí)現(xiàn)中簿煌,必須返回 一個(gè)IBinder 接口的實(shí)現(xiàn)類氮唯,供客戶端用來與服務(wù)進(jìn)行通信。無論是啟動(dòng)狀態(tài)還是綁定狀態(tài)姨伟,此方法必須重寫惩琉,但在啟動(dòng)狀態(tài)的情況下直接返回 null。
onUnbind():
當(dāng)另一個(gè)組件通過調(diào)用unbindService()與服務(wù)解綁時(shí)夺荒,系統(tǒng)將調(diào)用此方法瞒渠。
onRebind():
當(dāng)舊的組件與服務(wù)解綁后,另一個(gè)新的組件與服務(wù)綁定般堆,onUnbind()返回true時(shí)在孝,系統(tǒng)將調(diào)用此方法。
手動(dòng)調(diào)用:
啟動(dòng)——startService()
關(guān)閉——stopService()
綁定——bindService()
解綁——unbindService()
自動(dòng)調(diào)用:
創(chuàng)建——onCreat()
開始——onStartCommand()
銷毀——onDestroy()
綁定——onBind()
解綁——onUnbind()
啟動(dòng)方式一 (startService)
1淮摔、右鍵創(chuàng)建一個(gè)Service 私沮,會(huì)自動(dòng)在清單文件中創(chuàng)建,和Activity一樣。
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
Log.i(TAG, "MyService:++");
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind:++");
return null;
}
}
2和橙、在xml中布局
設(shè)置兩個(gè)按鈕仔燕,一個(gè)啟動(dòng)、一個(gè)停止
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/create_server_id"
android:text="啟動(dòng)一個(gè)服務(wù)"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/stop_server_id"
android:text="停止一個(gè)服務(wù)"
/>
</LinearLayout>
3魔招、MainActivity內(nèi)容
public class MainActivity extends AppCompatActivity {
private Button createServerId;
private Button stopServerId;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stopServerId = findViewById(R.id.stop_server_id);
createServerId = findViewById(R.id.create_server_id);
stopServerId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
createServerId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
});
}
}
如果服務(wù)已經(jīng)開啟晰搀,就不會(huì)重復(fù)的執(zhí)行 onCreate() ,而是調(diào)用 onStart() 或 onStartCommand()办斑。而服務(wù)停止的時(shí)候調(diào)用 onDestory()
一旦服務(wù)開啟跟開啟者就沒有任何關(guān)系;
開啟者退出之后外恕,服務(wù)還是可以在后臺(tái)長(zhǎng)期運(yùn)行的杆逗。前提是沒有調(diào)用 stopService(Intent);
開啟者不能調(diào)用服務(wù)里面的方法;
總結(jié):
啟動(dòng)方式:onCreate() — onStartCommand() — onDestroy()
開啟服務(wù):startService()
停止服務(wù):stopService()
啟動(dòng)方式二 (bindService)
使用Service的步驟如下:
1,定義一個(gè)Service類鳞疲,并繼承 Service
2,在 AndroidManifest.xml 中配置此 Service
3,使用 Context 的 bindService(Intent, ServiceConnection, int) 方法來啟動(dòng)此 Service
4,不使用該服務(wù)時(shí)罪郊,調(diào)用 unbindService(ServiceConnection) 方法停止此 Service
綁定服務(wù)不會(huì)調(diào)用 onStart() 或 onStartCommand() 方法。
注意:同一個(gè)服務(wù), 只能被同一個(gè)啟動(dòng)源, 綁定一次, 除非解綁后, 可以再次綁定
特點(diǎn):
bind的方式開啟服務(wù)尚洽,綁定服務(wù)悔橄,調(diào)用者掛了,服務(wù)也會(huì)跟著掛掉腺毫。
綁定者可以調(diào)用服務(wù)里面的方法癣疟。
1、創(chuàng)建服務(wù):自定義Service類繼承Service
public class MyService extends Service {
@Nullable
@Override
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind: ");
return new MyBinder();
}
public class MyBinder extends Binder{
public void callShow(){
show();
}
}
public void show(){
Log.i(TAG, "show:++");
}
//服務(wù)中提供的方法
public void methodOne(){
Toast.makeText(this, "methodOne", Toast.LENGTH_SHORT).show();
}
//服務(wù)中提供的方法
public void methodTwo(){
Toast.makeText(this, "methodTwo", Toast.LENGTH_SHORT).show();
}
}
2潮酒、清單文件注冊(cè)服務(wù)
<service android:name=".MyService"></service>
3睛挚、綁定服務(wù)和解除綁定
public class MainActivity extends AppCompatActivity {
private Intent intent;//開啟服務(wù)的意圖對(duì)象
private MyService myService;//通過綁定獲取Service
//綁定服務(wù)連接
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected: ");
MyService.MyBinder binder = (MyService.MyBinder) service;
binder.callShow();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.綁定服務(wù)
intent =new Intent(this,MyService.class);
//參數(shù)一:intent意圖 參數(shù)二:綁定服務(wù)連接 參數(shù)三:flag標(biāo)記BIND_AUTO_CREATE 綁定的時(shí)候自動(dòng)創(chuàng)建服務(wù)
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
//2.解除綁定服務(wù)
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
//3.點(diǎn)擊按鈕調(diào)用服務(wù)的方法
public void methodOne(View view){
myService.jiehun();
}
}
總結(jié):
綁定方式:onCreate() – onBind() — onUnbind() — onDestroy()
綁定服務(wù):bindService()
解除綁定:unbindService()
兩種的啟動(dòng)服務(wù)的特點(diǎn):
第一種,一旦啟動(dòng),只能手動(dòng)停止澈灼。
第二種竞川,可以調(diào)用服務(wù)里的方法。