1. 程式人生 > >android 四大元件之Service兩種呼叫方式使用詳解

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啟動方式

)和onBind(對應bindService啟動方式),實現每個一秒鐘列印一些內容的功能。

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方法