Service是Android四大組件之一(其餘是Activity、BroadcastReceiver)。作用是在後臺工作,比如播放着音樂時候啓動小說軟件,音樂仍然在播放;在後臺檢測網絡的變化等等;總而言之,在暗地裏默默付出的人。
Service在android四大組件中是與Activity最相似的組件,他們都代表可執行的程序。
區別:Service一直在後臺運行,沒有用戶界面。
選擇標準:如果某個程序組件需要在運行時向用戶呈現某種界面,或者與用戶交互,就需要用到Activity,否則使用Service了。
相似:
1、創建的步驟很像,先定義繼承子類,在AndroidManifest.xml文件中配置。
2、Service也具有自己的生命週期。
3、都是從Context派生出來的,都可以調用Context.getResources()、getContentResolver()等方法。
Service的兩種啓動模式:startService()、bindService()
- 通過Context的startService()來啓動Service,訪問者與Service之間沒有關聯,即使訪問者退出了,Service也仍然運行。
- 通過Context的bindService()來啓動Service,訪問者與Service綁定在一起,訪問者一旦退出,Service也結束。
號稱前者爲:持續不斷,後者稱爲一退就斷!
-------------------------------------------
接下來是startService的啓動和停止的代碼,該Activity的界面中包含2個按鈕,一個按鈕用於啓動Service,另一個用於停止Service。
Activity的代碼:
public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
private Button btnStartService;
private Button btnStoptService;//定義兩個按鈕
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartService = (Button) findViewById(R.id.btnStartService);
btnStoptService = (Button) findViewById(R.id.btnStoptService);//獲取兩個按鈕
btnStartService.setOnClickListener(this);
btnStoptService.setOnClickListener(this);//按鈕事件
}
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class); //1、創建啓動Service的Intent
switch (v.getId()) {
case R.id.btnStartService:
startService(intent); //2、啓動指定的Service
break;
case R.id.btnStoptService:
stopService(intent);//3、停止指定的Service
break;
}
}
}
調用Context裏的startService()、stopService()方法即可啓動、停止Service,操作十分簡單。而且程序使用了顯式Intent來啓動Service,因爲從5.0開始,Google要求必須使用顯式Intent啓動Service組件。我個人覺得這樣十分好,因爲像Service這樣使用頻率高,而且用到的地方都是比較重要部位,這樣會提高安全性吧。接下來是通過startService()啓動Service的生命週期:
context.startService() ->onCreate() ->onStartCommand() ->Service running
context.stopService() ->onDestroy() ->Service stop
如果Service已經運行,這是再點擊啓動按鈕,就不會再調用onCreate() 方法,則只會調用onStartCommand()方法,而且可以執行多次.
總結得出 onCreate->onStartCommand(可以多次調用) ->onDestroy
--------------------------------
接下來是bindService()綁定本地Service,並與之通信。
當程序使用startService()來啓動Service時,Service和訪問者無法進行通信、交換數據。因此如果需要做以上動作,就應該使用bindService()和unbindService方法來啓動、關閉Service。
Context的bindService()方法的完整方法簽名爲:bindService(Intent service,ServiceConnection conn,int flags)
Intent service:該參數通過Intent指定要啓動的Service。
ServiceConnection conn:該對象用於監聽訪問者與Service之間的連接情況(一般情況爲this,但要實現ServiceConnection)。
int flags:指定綁定時是否自動創建Service(該參數可以指定0(不自動創建)或BIND_AUTO_CREATE(自動創建))。
當開發Service類時,該Service類必須提供一個IBinder onBind(Intent intent)方法,在綁定本地Service的情況下,onBind(Intent intent)方法所返回的IBinder對象將會傳給ServiceConnection對象裏onServiceConndected()方法的service參數,這樣訪問者就可以通過IBinder對象與Service進行通信了。
實際上,開發通常會採用繼承Binder(IBinder的實現類)的方式實現自己的IBinder對象。
接下來在Activity中綁定本地Service:
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return new Binder();//返回一個Binder對象
}
@Override
//當啓動成功後會執行的方法
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
new Thread() {
public void run() {
super.run();
while (ture) {
System.out.println("服務正在運行中...");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("onDestroy");
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onUnbind");
return super.onUnbind(intent);
}
}
MainActivity 的代碼如下
public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
private Button btnStartService;
private Button btnStoptService;
private Button btnBindService; //綁定服務
private Button btnUnBindService;//解除綁定服務
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartService = (Button) findViewById(R.id.btnStartService);
btnStoptService = (Button) findViewById(R.id.btnStoptService);
btnBindService = (Button) findViewById(R.id.btnBindService);//綁定服務
btnUnBindService = (Button) findViewById(R.id.btnUnBindService);//解除綁定服務
btnStartService.setOnClickListener(this);
btnStoptService.setOnClickListener(this);
btnBindService.setOnClickListener(this);//按鈕事件
btnUnBindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class); //指定Intent
switch (v.getId()) {
case R.id.btnStartService:
startService(intent);
break;
case R.id.btnStoptService:
stopService(intent);
break;
case R.id.btnBindService:
bindService(intent, this, Context.BIND_AUTO_CREATE);//綁定服務
break;
case R.id.btnUnBindService:
unbindService(this);//解除綁定服務
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {//服務被綁定成功的時候運行
System.out.println("onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) { //進程被殺掉 或者 奔潰的時候運行
System.out.println("onServiceDisconnected");
}
使用context.bindService()啓動Service的經歷:context.bindService() -> onCreate() ->onBind() ->Service running
unbindService() -> onUnbind() -> onDestroy() ->Service stop
總而言之,onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。