天天看點

Android 四大元件之service

Service為安卓四大元件之一,學會使用service是作為一個優秀的程式員必備的技能。Service運作在主線程之中,可以在Activity界面銷毀的時候依然在背景運作。不能直接在Service裡面直接進行耗時的操作,會導緻ANR。Service有兩種,一種是遠端服務,一種是本地服務。遠端服務指的是不同程序間通信的服務(一般情況下也可以了解為一個App就是一個程序),本地服務是在同一個程序間通信的服務。Service的啟動方式有兩種,一種是在Activity裡面使用startService(),另一種在Activity裡面使用BindService()。需要在Manifest檔案裡面注冊,如果不注冊雖然不報錯但是無法啟動Service。使用BindService()啟動需要在必要的時候調用unbindservice(),不然報異常。Service也可以運作在前台,提高其優先級别,使其不容易被系統殺死。本文将Service的使用示範一遍,最後做一個Demo實作天氣的查詢(天氣資料來源于Weather.com)

Service使用場合:

1.一個或多個Activity需要向同一應用中的Service發出執行某一操作的指令。

2、當界面銷毀時還需要在背景操作任務,比如播放音樂,下載下傳資料等,重新進入的時候還能控制進度的時候。

Service與Thread的差別:

有很多人以為Service是一個線程,這個是錯誤的,因為Service就運作在主線程中,打開一個Service并不是開了一個新的線程。Service中也不能做耗時操作,否則會導緻ANR(彈出應用程式無響應)。Thread是單獨的開一個線程,可以在這個線程中做耗時的操作,不過在這個線程中不能操作UI,而在Service裡可以操作UI。那麼為什麼要弄一個Service 呢?我覺得主要是為了在Activity銷毀的時候app還能繼續工作,并且在Activity重新建立的時候還能控制其啟動的Service,而如果是Thread的話當界面銷毀再次進入的時候就無法控制thread了。

生命周期:

start方式啟動:oncreate()-->onstartcommand()-->onstart()-->onstop()-->ondestroy()

bind方式啟動:oncreate()--->onbind()-->unbind()--->ondestroy();

使用步驟:

1.建立一個類WeatherService繼承

2.在manifest檔案裡面注冊

3.使用對應的啟動方式啟動Service

先來看效果:

Android 四大元件之service

因為涉及到網絡的操作,本來想着定義一個回調接口傳回資料,可是怎麼都無法成功擷取資料,最後隻能用廣播的形式把Service擷取的資料傳回給Activity。

在MainActivity中:

@Override
	protected void onResume() {
		super.onResume();
		// 單綁定成功的時候調用這裡
		sc = new ServiceConnection() {
			// 與服務斷開連接配接
			@Override
			public void onServiceDisconnected(ComponentName name) {

			}

			// 與服務連接配接上了
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				// 強轉為Mybinder
			}
		};
		// 注冊一個廣播接收資料
		broadcast = new BroadcastReceiver() {

			@Override
			public void onReceive(Context context, Intent intent) {
				json = intent.getStringExtra("result");
				ParseJson();

			}
		};
		registerReceiver(broadcast, new IntentFilter("com.xinxue.RESULTBROADCAST"));

	}
           

在Service中:

public class WeatherService extends Service {
	private String TAG = "WeatherService";
	public String result;
	private MyBinder binder;
	private String city;
	private String code;

	// 綁定
	@Override
	public IBinder onBind(Intent intent) {
		Log.e(TAG, "onBind");
		city = intent.getStringExtra("city");
		downLoad();
		return binder;
	}

	public class MyBinder extends Binder {
		public WeatherService getService() {
			return WeatherService.this;
		}

		// 下載下傳資料
		public String getResult() {
			return result;
		};
	}

	@Override
	public boolean onUnbind(Intent intent) {
		Log.e(TAG, "onUnbind");
		return super.onUnbind(intent);
	}

	@Override
	public void onRebind(Intent intent) {
		Log.e(TAG, "onRebind");
		super.onRebind(intent);
	}

	// 建立
	@Override
	public void onCreate() {
		Log.e(TAG, "onCreate");
		binder = new MyBinder();
		super.onCreate();
	}

	// 啟動
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.e(TAG, "onStartCommand");
		city = intent.getStringExtra("city");
		downLoad();
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public boolean stopService(Intent name) {
		Log.e(TAG, "stopService");
		return super.stopService(name);
	}

	@Override
	public void onDestroy() {
		Log.e(TAG, "onDestroy");
		super.onDestroy();
	}

	// 開一個線程去下載下傳
	private void downLoad() {
		try {
			code = URLEncoder.encode(city, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		new Thread(new Runnable() {

			@Override
			public void run() {
				String url = "http://op.juhe.cn/onebox/weather/query?cityname=" + code
						+ "&key=0e9d91775e452d72d89dbf40d197cd2a";
				result = HttpUtils.httpGet(url);
				Intent intent = new Intent();
				intent.setAction("com.xinxue.RESULTBROADCAST");
				intent.putExtra("result", result);
				sendBroadcast(intent);
			}
		}).start();

	}

}
           

掃描關注我的微信公衆号:

Android 四大元件之service

示例下載下傳:

              去下載下傳咯~~