參考文章:http://www.runoob.com/w3cnote/android-tutorial-service-1.html
Service是Android提供一個允許長時間留駐後臺的一個組件,最常見的 用法就是做輪詢操作!或者想在後臺做一些事情,比如後臺下載更新!
Android中使用Service的方式有兩種:
1)StartService()啓動Service
2)BindService()啓動Service
StartService()和BindService()的區別:
通過前者啓動的service,調用者和service無必然聯繫,當調用者銷燬時,service不會銷燬而是一直運行,只有調用了StopService纔會停止;通過後者啓動的service,調用者和service是相互關聯的,調用者銷燬,那麼service也會銷燬,如果是多個調用者綁定一個service,其中一個調用者想解除綁定只需調用unbindService(),當所有調用者都解除綁定,service便會銷燬。
1.StartService
先上代碼:
TestService1.java
public class TestService1 extends Service{
private final String TAG="TestService";
//必須要實現的方法
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "onBind方法被調用");
return null;
}
//service創建時被調用
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i(TAG, "onCreate方法被調用");
super.onCreate();
}
//service被啓動時調用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i(TAG, "onStartCommand方法被調用");
return super.onStartCommand(intent, flags, startId);
}
//service被關閉時調用
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.i(TAG, "onDestroy方法被調用");
super.onDestroy();
}
}
<!-- 配置Service組件,同時配置一個action -->
<service android:name=".TestService1">
<intent-filter >
<action android:name="com.example.buttondemo.TestService1"/>
</intent-filter>
</service>
MainActivity.java
public class MainActivity extends Activity implements OnClickListener{
private Button btn_start,btn_stop;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start=(Button)findViewById(R.id.btn_start);
btn_stop=(Button)findViewById(R.id.btn_stop);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
//創建啓動Service的Intent,以及Intent屬性
intent=new Intent();
intent.setAction("com.example.buttondemo.TestService1");
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_start:
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
default:
break;
}
}
}
運行截圖:
如圖:
第一次點擊開始服務,onCreate和onStartCommand方法被調用,再點擊開始服務,onCreate方法不再被調用,onStartCommand被調用,直到點擊停止服務,onDestroy方法被調用。
①首次啓動會創建一個Service實例,依次調用onCreate()和onStartCommand()方法,此時Service 進入運行狀態,如果再次調用StartService啓動Service,將不會再創建新的Service對象, 系統會直接複用前面創建的Service對象,調用它的onStartCommand()方法!
②但這樣的Service與它的調用者無必然的聯繫,就是說當調用者結束了自己的生命週期, 但是隻要不調用stopService,那麼Service還是會繼續運行的!
③無論啓動了多少次Service,只需調用一次StopService即可停掉Service
2.BindService
Step 1:在自定義的Service中繼承Binder,實現自己的IBinder對象
Step 2:通過onBind( )方法返回自己的IBinder對象
Step 3:在綁定該Service的類中定義一個ServiceConnection對象,重寫兩個方法, onServiceConnected和onDisconnected!然後直接讀取IBinder傳遞過來的參數即可!
TestService2.java:
public class TestService2 extends Service {
private final String TAG = "TestService2";
private int count;
private boolean quit;
//定義onBinder方法所返回的對象
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder
{
public int getCount()
{
return count;
}
}
//必須實現的方法,綁定改Service時回調該方法
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind方法被調用!");
return binder;
}
//Service被創建時回調
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate方法被調用!");
//創建一個線程動態地修改count的值
new Thread()
{
public void run()
{
while(!quit)
{
try
{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}
count++;
}
};
}.start();
}
//Service斷開連接時回調
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind方法被調用!");
return true;
}
//Service被關閉前回調
@Override
public void onDestroy() {
super.onDestroy();
this.quit = true;
Log.i(TAG, "onDestroyed方法被調用!");
}
@Override
public void onRebind(Intent intent) {
Log.i(TAG, "onRebind方法被調用!");
super.onRebind(intent);
}
}
在AndroidManifest.xml中對Service組件進行註冊:
<service android:name=".TestService2" android:exported="false">
<intent-filter>
<action android:name="com.jay.example.service.TEST_SERVICE2"/>
</intent-filter>
</service>
MainActivity.java:
public class MainActivity extends Activity {
private Button btnbind;
private Button btncancel;
private Button btnstatus;
//保持所啓動的Service的IBinder對象,同時定義一個ServiceConnection對象
TestService2.MyBinder binder;
private ServiceConnection conn = new ServiceConnection() {
//Activity與Service斷開連接時回調該方法
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("------Service DisConnected-------");
}
//Activity與Service連接成功時回調該方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("------Service Connected-------");
binder = (TestService2.MyBinder) service;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnbind = (Button) findViewById(R.id.btnbind);
btncancel = (Button) findViewById(R.id.btncancel);
btnstatus = (Button) findViewById(R.id.btnstatus);
final Intent intent = new Intent();
intent.setAction("com.jay.example.service.TEST_SERVICE2");
btnbind.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//綁定service
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
btncancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//解除service綁定
unbindService(conn);
}
});
btnstatus.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Service的count的值爲:"
+ binder.getCount(), Toast.LENGTH_SHORT).show();
}
});
}
}
運行圖如下:
點擊鎖定service:
再次點擊鎖定service,沒有任何反應。
點擊獲取service狀態
點擊解除service:
使用BindService綁定Service,依次調用onCreate(),onBind()方法, 我們可以在onBind()方法中返回自定義的IBinder對象;再接着調用的是 ServiceConnection的onServiceConnected()方法該方法中可以獲得 IBinder對象,從而進行相關操作;當Service解除綁定後會自動調用 onUnbind和onDestroyed方法,當然綁定多客戶端情況需要解除所有 的綁定纔會調用onDestoryed方法進行銷燬!