android學習之Service

       服務是安卓中的典型組件,一般組件都需要在清單文件中註冊。服務能夠長時間的運行在後臺,並且不提供用戶界面。其他的組件能夠開啓服務 並且在用戶在開啓其他應用的時候該服務仍然能夠繼續在後臺執行。一個組件通過bind的方式綁定服務,並且該組件能與之交互。

最典型的案列就是播放音樂,播放器應用在後臺仍然能夠播放音樂。

服務,簡單的解釋就是,長期在後臺運行並且沒有界面的組件。類似天氣預報和股票顯示的應用,需要在後臺連接服務器,

每隔一段時間,獲取最新的數據。Service不需要在activity中開啓子線程。

服務有兩種開啓方式:

第一種:採用start的方式開啓服務

Intent intent = new Intent(this,MyService.class);
		startService(intent);
這種方式類似於Activity的創建,通過Intent來實現,同時停止服務和開啓服務類似:

Intent intent = new Intent(this,MyService.class);
		stopService(intent);
用這種方式創建Service的生命週期如下:onCreate()--> onStartCommand()  ---> onDestory(),有一個onStart()的過時的方法,需要服務處理的邏輯一般在onStartCommand和onStart裏面執行。這裏需要注意的幾點:

一、如果服務重複開啓,當再次執行startService方法時,不再執行onCreate方法,而是直接執行onStartCommand方法;

二、服務停止的時候,顯然會執行onDestory方法,並且只會執行一次該方法,重複調用stopService方法時沒用的。

這種方式開啓服務的特點:採用start方式開啓的服務。一旦服務開啓了,就和開啓者沒有關係,這時候開啓者(一般是Activity組件)

被銷燬後,服務仍然在後臺執行;這種方式開啓的服務還有一個缺點就是開啓者無法調用服務內部的方法,也就是無

法與服務進行交互。

第二種:採用bind的方式開啓服務

採用這種bind的方式開啓服務主要是爲了能夠調用Service中的方法,那麼如何通過綁定服務的方式來調用服務裏面的方法呢?
可以分成5個步驟:
一、首先Service中要暴露出方法,定義一個內部類,這個內部類相當於中介,由中介這個內部成員來幫我們幹活,即調用
Service內部的方法。
二、繼承Service默認有一個方法onBind,通過這個onBind將中介的信息傳遞出去,也就是返回一個new 出來的中介
對象,而且onBind的返回值是IBinder,而這個中介必須是IBinder類型,所以中介這個內部類需要繼承Binder類或實
現IBinder接口。
三、定義一個內部類實現ServiceConnection接口來獲得中介對象,以便能夠調用Service裏面的方法。
四、在Activity中採用綁定的形式開啓服務。bindService(Intent service, ServiceConnection conn,int flags)這個方法有
三個參數,第一個是一個意圖,第二個是ServiceConnection,這是一個接口,通過這個接口可以獲得第二步
中onBind方法返回的中介對象,所以這裏需要我們去實現這個接口。第三個參數表示綁定服務的操作,
比如BIND_AUTO_CREATE-->表示綁定的時候自動創建服務。
五、通過中介調用Service裏面的方法。
這就是以上五個步驟。
這種方式開啓服務時服務的生命週期:
onCreate() --->onBind();--->onunbind()-->onDestory();
綁定服務不會調用onstart或者onstartcommand方法;
下面是第二種方式開啓的服務的部分代碼:
package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyService extends Service {

	public MyService() {
	}
	@Override
	//2、返回中介對象
	public IBinder onBind(Intent intent) {
		return new Agency();
	}

	@Override
	public void onCreate() {
		System.out.println("服務onCreate");
		super.onCreate();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("服務onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}
	@Override
	public void onDestroy() {
		System.out.println("服務onDestory");
		super.onDestroy();
	}
	
	public void methodInService() {
		System.out.println("服務裏的方法被執行");
	}
	
	/**
	 * 1、中間人,相當於調用者Activity和Service之間的橋樑
	 */
	private class Agency extends Binder implements IAgency{
		public void callMethodInService(int money) {
			if(money>50) {
				methodInService();
			} else {
				System.out.println("錢不夠,不給幹活。。。。");
			}
		}
	}
}

package com.example.service;

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 IAgency agency;
	private MyConn conn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	//4、以bind的方式開啓服務
	public void bind(View view) {
		Intent intent = new Intent(this,MyService.class);
		conn = new MyConn();
		bindService(intent, conn, BIND_AUTO_CREATE);
	}

	public void unbind(View view) {
		unbindService(conn);
	}
	//5、通過中介來調用方法
	public void call(View view) {
		agency.callMethodInService(55);
	}
	@Override
	protected void onDestroy() {
		System.out.println("Activity 被銷燬");
		super.onDestroy();
	}
	//3、通過實現ServiceConnection來獲得中介對象
	private class MyConn implements ServiceConnection {
		@Override
		//當服務連接的時候或者被成功綁定的時候調用
		public void onServiceConnected(ComponentName name, IBinder service) {
			System.out.println("在Activity中成功得到了中間人。。。");
			agency = (IAgency) service;
		}
		@Override
		//當服務失去連接的時候調用,(一般進程掛了,服務被異常終止)
		public void onServiceDisconnected(ComponentName name) {
			
		}
		
	}
}
還有一個地方需要注意:就是在服務被解除的時候,將調用onDestory方法,Service被銷燬,但是Service中的內部類也就是中介並沒有被銷燬,所以一般在調用unbindService方法之後,一般會將中介對象置爲null。
最後附上Android api中的service生命週期圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章