android 四大元件之Service兩種呼叫方式使用詳解
一 概述
Service服務作為android中的四大元件之一,其作用和重要性也不用多說。service用於長期在後臺處理任務,與Activity相反Service沒有可見的使用者介面,但Service能長時間在後臺執行,Service是一個具有較長生命週期但沒有使用者介面的元件,和Activity一樣的是Service也有自己的生命週期。下圖是它的生命週期的過程。
service有2種基本的啟動方式:
startService():使用這種方式,來進行單一的任務,不需要返回結果給呼叫者
bindService():使用這種方式,能和呼叫者進行繫結,是兩者有關聯。
二 Service的建立,並在AndroidManifest檔案中進行配置。
建立自己的Service需繼承android提供的Service類,並更具功能實現其中的方法。檢視Service類中的方法。
下面對幾個重要的方法進行講解:
onCreate();當服務被建立時呼叫,只調用一次。
onStartCommand();它與startService()對應,當服務啟動後呼叫。如果你重寫了該方法,你就有責任自己去
當任務結束以後,呼叫stopSelf()或者stopService()來停止服務。如果你是繫結的服務,就不需重寫該方法了。
onBind();它與bindService()對應,通過返回IBinder,來與service交流。如果你並不像繫結它,就直接返回null
onDestroy();當服務不再被使用時需要銷燬時呼叫,你應該在這裡用來停止執行緒,登出監聽器,廣播。
如果一個元件如activity使用的是 startService()來啟動服務的話,就會觸發 onStartCommand(),然後服務就會一直執行,直到任務結束;服務的停止需要
手動控制:在啟動服務的元件中呼叫 stopService()或者在服務本類中呼叫stopSelf()
如果一個元件使用的是bindService()來啟動服務的話,該服務就會執行,直到元件不約束它。
三 程式碼示例
1. 建立自己的Service,並重寫onStartCommand(對應startService啟動方式
package com.example.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
/**
* @author ZMC
*建立自定義的service
*/
public class FirstService extends Service {
private MyBinder myBinder = new MyBinder();
//建立一個Binder類
class MyBinder extends Binder{
public void startJob(){
new Thread(){
public void run() {
for (int i = 0; i < 51; i++) {
System.out.println("startJob");
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
}
//該方法給呼叫者返回一個IBinder物件,是和呼叫者經行資料交換的關鍵
//該方法和bindService對應
@Override
public IBinder onBind(Intent intent) {
Log.i("test", "onBind");
return myBinder;
}
@Override
public void onCreate() {
System.out.println("Oncreate");
super.onCreate();
}
private boolean flag = true;
private int count = 1;
//該方法是和startService對應的
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
new Thread() {
@Override
public void run() {
while (flag) {
System.out.println("count:" + count);
count++;
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (count > 100) {
flag = false;
}
}
}
}.start();
Log.i("test","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
//銷燬方法
@Override
public void onDestroy() {
// TODO Auto-generated method stub
System.out.println("ondestory");
super.onDestroy();
}
}
說明:
onStartCommand方法是對應startService啟動方式的方法,使用startService方式啟動只需要將要實現的功能寫在onStartCommand即可。
onBind方法,該方法給呼叫者返回一個IBinder物件,是和呼叫者經行資料交換的關鍵,該方法和bindService對應,其中IBinder物件一般是自己整合Binder類實現的,上面例子中是MyBinder,其中定義了實現功能的方法,這樣在當呼叫者得到該物件時,就能通過該物件中的方法實現相對應的功能了。
2. 佈局檔案
定義了四個按鈕
通過四個按鈕實現啟動服務,暫停服務。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.servicedemo.MainActivity" >
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="start"
android:text="啟動服務"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="停用服務"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="bind"
android:text="繫結Activity"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="unbind"
android:text="解綁Activity"/>
</LinearLayout>
3.
建立呼叫者
這裡我用了Activity作為服務的呼叫者,並通過一個ServiceConnection介面的實現類來實現和Service的繫結。
package com.example.servicedemo;
import com.example.servicedemo.FirstService.MyBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class MainActivity extends Activity {
private Intent intent = null;
private MyBinder myBinder;
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyBinder)service;
myBinder.startJob();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View view){
/*
* 這樣開啟的服務是不受activity生命週期的影響的
* 沒有辦法和其他的元件進行資料互動 它是一個單獨的個體
* */
intent = new Intent(this,FirstService.class);
startService(intent);
}
public void stop(View view){
if (intent!=null) {
stopService(intent);
}
}
public void bind(View view){
intent = new Intent(this,FirstService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
public void unbind(View view){
unbindService(serviceConnection);
}
}
說明:
start和stop對應的是啟動服務和停用服務兩個按鈕的事件,同時對應為startService的啟動方式。
bind和unbind對應的是繫結Activity和解綁Activity兩個按鈕的事件,對應bindService方式啟動的。
重點:ServiceConnection該介面是一個呼叫者和Service關聯的介面,通過該介面的實現類即可實現兩者的互動。上面的程式碼示例中通過匿名內部類來實現的,其中實現onServiceConnected方法,該方法就是用來接收Service中onBind返回的IBinder物件的。
四 結果:
點選啟動服務按鈕呼叫onCreate和onStartCommand方法
點選停用服務呼叫呼叫ondestory方法
點選繫結按鈕呼叫onCreate和onBind方法
點選解綁按鈕呼叫ondestory方法