天天看點

Android之四大元件(Service的開啟與關閉) 前言Service基礎

個人開發的微信小程式,目前功能是書籍推薦,後續會完善一些新功能,希望大家多多支援!

Android之四大元件(Service的開啟與關閉) 前言Service基礎

前言

服務(Service)是Android系統中的四大元件之一。服務主要用于兩個目的:背景運作和跨程序通路。通過啟動

一個服務,可以在不顯示界面的前提下在背景運作指定的任務,這樣可以不影響使用者做其他事情。通過AIDL服務可以

實作不同程序之間的通信,這也是服務的重要用途之一。

Service基礎

Service并沒有實際界面,而是一直在Android系統的背景運作。一般使用Service為應用程式提供一些服務,或不

需要界面的功能,例如下載下傳檔案、播放音頻等。

如何建立與配置Service

在日常開發中Service的建立與配置可以按照以下兩個步驟進行:

(1)定義一個繼承Service的子類。

(2)在AndroidManifest.xml檔案中配置該Service。

Service與Activity一樣,也有一個啟動到銷毀的過程,不過這個過程Service要比Activity簡單多了。一個服務實際

上是一個繼承自android.app.Service的類。檢視Service源碼,可以看出Service實際上是一個抽象類,在這個抽象類

中有一個抽象方法onBind,是以我們在繼承一個Service類時,必須要實作這個方法。

public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
	.......
	public abstract IBinder onBind(Intent intent);
	.......
}
           

下面類定義了一個Service元件。

public class MyFirstService extends Service{

	public static final String TAG="MyFirstService";
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.e(TAG, "--------onCreate--------");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.e(TAG, "--------onStartCommand--------");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.e(TAG, "--------onDestroy--------");
	}

}
           

以上代碼完成了建立Service,接下來需要在AndroidMainfest.xml檔案中進行配置該Service,以下配置代碼展示了

如何配置Service:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.example.servicetest.startservice.MyFirstService" >
        </service>
    </application>
           

到了這一步我們的Service元件已經建立完畢。接着我們可以啟動Service了,在Android系統中啟動Service有兩種

方式,分别是startService和bindService。

startService使用

下面程式通過兩個按鈕進行啟動與停止Service,示範Service通過startService從建立到銷毀整個過程。

public class MyFirstService extends Service{

	public static final String TAG="MyFirstService";
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.e(TAG, "--------onCreate--------");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.e(TAG, "--------onStartCommand--------");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.e(TAG, "--------onDestroy--------");
	}

}
           

兩個按鈕的點選事件:

@Override
public void onClick(View v) {
	switch (v.getId()) {
	case R.id.btn_startService:// startService
		startService(serviceIntent);
		break;
	case R.id.btn_stoptService:// stopService
		stopService(serviceIntent);
		break;
	default:
		break;
      }
}
           

以上是我們建立的Service元件,接下來對Service進行操作。

(1)當單擊一次啟動(startService)按鈕時:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

(2)當服務被啟動後單擊一次停止(stopService)按鈕時:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

從上面可以看出Service從建立到銷毀分别經曆了 onCreate---->onStartCommand---->onDestroy

(3)當我們重複開啟Service時:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

從上圖可以看出,每當Service被建立時回調onCreate方法,每次Service被啟動時都會回調onStartCommand方

法,多次啟動一個已有的Service元件将不會再回調onCreate方法,但每次啟動時都會回調onStartCommand方法。

其中,當我按下home鍵時,并沒有回調onDestroy方法,也就是說此Service并沒有随着Android系統的關閉而關

閉。

bindService的使用

使用startService方法啟動服務,當程式被強制退出時,并且沒有調用stopService來停止服務,Service會保持在

背景一直運作,直到Android系統關閉或調用stopService方法後才會停止。如果我們希望在啟動服務的Activity關閉後

服務自動關閉,這就需要将Activity和Service進行綁定。

通過bindService方法可以将Activity和Service綁定。bindService方法的定義如下:

public boolean bindService(Intent service, ServiceConnection conn,int flags) 
           

該方法的三個參數含義如下:

(1)service:該參數通過Intent指定要啟動的Service。

(2)conn:該參數的類型是ServiceConnection,負責連接配接Intent對象指定的服務。當通路者與Service之間連接配接

成功時将回調ServiceConnecttion對象的onServiceConnected(ComponentName name,IBinder service)方法;當

Service所在的宿主程序由于異常終止或由于其他原因終止,導緻該Service與通路者之間斷開連接配接時回調

ServiceConnection對象的onServiceDisconnected(ComponentName name)方法。

(3)flags:該參數是一個标志位,一般設為Context.BIND_AUTO_CREATE。

以下建立了一個繼承Service的類,在該類中增加了幾個與綁定相關的事件方法:

public class MyFirstService extends Service{
	
	private String info;
	private MyBinder myBinder=new MyBinder();

	public static final String TAG="MyFirstService";

	/**
	 * 重新綁定時調用該方法
	 */
	@Override
	public void onRebind(Intent intent) {
		super.onRebind(intent);
	}
	
	/**
	 * 解除綁定時調用該方法
	 */
	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		return myBinder;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.e(TAG, "--------onCreate--------");
		info="onCreate";
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.e(TAG, "--------onStartCommand--------");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.e(TAG, "--------onDestroy--------");
	}
	
	public class MyBinder extends Binder{
		public String getInfo(){
			return info;
		}
	}

}
           
public class MainActivity extends Activity implements OnClickListener {

	private Button btn_startService;
	private Button btn_stopService;
	private Button btn_bindService;
	private Button btn_unbindService;
	private Button btn_getinfo;

	private Intent serviceIntent;

	private MyFirstService.MyBinder myBinder;

	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.e(MyFirstService.TAG, "------onServiceDisconnected---------");
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.e(MyFirstService.TAG, "------onServiceConnected---------");
			myBinder = (MyFirstService.MyBinder) service;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initData();
		initView();
		initEvent();
	}

	private void initData() {
		serviceIntent = new Intent(this, MyFirstService.class);
	}

	private void initView() {
		btn_startService = (Button) this.findViewById(R.id.btn_startService);
		btn_stopService = (Button) this.findViewById(R.id.btn_stoptService);
		btn_bindService = (Button) this.findViewById(R.id.btn_bindService);
		btn_unbindService = (Button) this.findViewById(R.id.btn_unbindService);
		btn_getinfo = (Button) this.findViewById(R.id.btn_getinfo);
	}

	private void initEvent() {
		btn_startService.setOnClickListener(this);
		btn_stopService.setOnClickListener(this);
		btn_bindService.setOnClickListener(this);
		btn_unbindService.setOnClickListener(this);
		btn_getinfo.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_startService:// startService
			startService(serviceIntent);
			break;
		case R.id.btn_stoptService:// stopService
			stopService(serviceIntent);
			break;
		case R.id.btn_bindService:// bindService
			bindService(serviceIntent, conn, Service.BIND_AUTO_CREATE);
			break;
		case R.id.btn_unbindService:// unbindService
			unbindService(conn);
			break;
		case R.id.btn_getinfo:// 擷取資料
			Toast.makeText(MainActivity.this, myBinder.getInfo(),
					Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}
	}

}
           

運作效果:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

在MyFirstService類中定義了一個MyBinder類,該類用于擷取一個String類型的傳回值,

ServiceConnection.onServiceConnected方法的第2個參數是一個IBinder類型的變量,将該參數轉換成

MyFirstService.MyBinder對象,并使用myBinder.getInfo()方法擷取String類型的值。

接着看下我們是如何使用bindService和unbindService操作的。

(1)當我們單擊一次bindService(bindService(service,conn,flags))按鈕時:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

(2)當我們單擊一次unbindService按鈕時:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

從上面可以看出通過bindService開啟服務,再通過unbindService停止服務的過程是 onCreate------>onBind------

->onServiceConnected------->onUnbind------>onDestory

這裡面值得注意的是,當我按下home鍵時,此時并沒有調用unbindService方法進行停止服務,但依然能列印出

onUnbind---->onDestory,也就是說通過bindService開啟的服務是随着Activity的銷毀而銷毀。

Service的生命周期

下圖的左半部分是通過startService()方法啟動時的Service生命周期,右半部分是通過bindService()方法啟動時

的Service生命周期。

Android之四大元件(Service的開啟與關閉) 前言Service基礎

Service生命周期有一種特殊的情形,如果Service已由某個用戶端通過startService()方法啟動了,接下來其他客

戶端再調用bindService()方法來綁定該Service後,再調用unbindService()方法解除綁定,最後又調用了bindService()

方法再次綁定到Service,這個過程所觸發的生命周期如下:

Android之四大元件(Service的開啟與關閉) 前言Service基礎

進行拆解步驟:

(1)調用startService時的生命周期:onCreate------>onStartCommand

(2)調用bindService時的生命周期:onBind------>onServiceConnected

(3)調用unbindService時的生命周期:onUnbind

(4)再一次調用bindService時的生命周期:onServiceConnected----->onRebind

以上調用unbindService時,并沒有回調onDestroy()方法,這是因為該Service并不是由Activity通過bindService()

方法來啟動的,是以當Activity調用unbindService()方法取消與該Activity的綁定時,該Service也不會終止。當Activity

調用bindService()綁定一個已經啟動的Service時,系統隻是把Service内部IBinder對象傳給Activity,當Activity調用

unbindService()方法取消與該Service的綁定時,隻是切斷了Activity與Service之間的聯系,并不能停止Service元件。

-------------------------------------------------------------------------------------------------------------------------------------------------------

轉載請注明出處:http://blog.csdn.net/hai_qing_xu_kong/article/details/47722185情緒控