android基礎之Service

                                                                             android基礎之Service

一:Service的概述

   Service是Android四大基本組件(Service,Activity,Context Provider,BroadcastReceiver它們之間依靠Intent建立聯繫)中與Activity最相似的組件。都代表 執 行的程序,Service與Activity的區別在於:

   Service一直在後臺運行,它沒有用戶界面,所以絕不會到前臺 來。一旦Service被啓動起來之後,它就與Activity一樣。完全具有自己的生命週期。

   關於程序中Activity和service的選擇標準:

   如果某個程序組件需要在運行時向用戶呈現某種界面,或者該程序需要與用戶交互,就需要使用Activity,否則就應該考慮使用Service了。

   如:下載東西,播放音樂。可以一邊下載,一邊播放,一邊玩其他的事情。但是Activity是無法做到的。只要Activity被關閉或者最小化了,程序就停止了。

二:特點

1.沒有UI

2.進行耗時較長或者與用戶沒有交互的一些功能

3.Service具有較高的優先級,比stop的Activity優先級要高,最高的優先級是前臺Activity

4.具有較長的生命週期




三.使用


看到這裏你也許會問爲什麼Service會有2中生命週期呢。哈哈,

其實這是跟Service的使用方式有關的。Service有2中不同的使用方式。

我們先創建一個android application project工程,然後在默認包下新建一個class,取名爲firstService 繼承Service如圖:


既然Service是我們自定義的,當然我們要在清單文件裏面註冊一下。(在AndroidManifest.xml的 <application>標籤加入如下內容):


name裏面放的是類的包名+類名,一般會有提示。

第一種使用方式(對應最左邊的圖)



這裏我在主界面放了個按鈕,然後設置的android:onClick="btn2"

這種方式啓動的Service,並沒有將之與Activity綁定,所以作爲一個單獨存在的實體,本身的生命週期不受別人影響。也沒有辦法與其他組件之間進行數據交互。

就像我們電腦的一些一些系統服務一樣,很多時候我們是通過強制手段關閉的。


第二種方式,對應最右邊的圖。

通常情況下,我們希望一個後臺的Service是可控的,同時用戶也希望知道這個服務的運行狀態,就拿下載東西來說,有的時候用戶希望看到實時的數據變化。第一種方式在這種情況下顯然不能滿足我們的需求,畢竟大多數場景下,用戶希望服務受自己掌控,同時靈活的數據是app的靈魂。

我們知道,service沒有ui所以要通過Activity提供ui。第二種方式就是通過activity與service的綁定實現的。用同樣的方式,我們在佈局裏面再放一個按鈕,然後設置的android:onClick="btn1"在activity的主函數裏面定義按鈕點擊事件。


前面都差不多。就啓動時用

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

啓動。原理都說的差不多了。建議寫代碼時對着生命週期來寫。

package com.example.mydemo;

import com.example.mydemo.secondService.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;
import android.widget.Toast;

public class MainActivity extends Activity {

	private mybinder mybinder;
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		//當訪問者與之連接成功時調用
		@Override
		public void onServiceConnected(ComponentName name, IBinder ibinder) {
			// TODO Auto-generated method stub
			mybinder = (com.example.mydemo.secondService.mybinder) ibinder;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	/**
	 * startService所啓動的服務
	 * 1.它是不受任何人影響的
	 * 2.它是作爲一個單獨的個體存在的,沒有辦法與其他組件之間進行數據交互
	 * @param view
	 */
	public void btn(View view){
		Toast.makeText(MainActivity.this, mybinder.getCount()+"", Toast.LENGTH_LONG).show();
	}
	
	public void btn1(View view){
		unbindService(serviceConnection);
	}
	
	public void btn2(View view){
		Intent intent = new Intent(this,secondService.class);
	//	startService(intent);
		bindService(intent, serviceConnection, BIND_AUTO_CREATE);
	}

	/**
	 * 如果使用bindServiuce啓動的服務,那麼service就與調用者的生命週期就有關聯了,
	 * 所以退出時也要終止service
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unbindService(serviceConnection);
		super.onDestroy();
	}
	
	
	
}

創建2個service自己隨便取名字,別忘了在清單文件註冊就是。


第一個service對應第一種啓動方式:

package com.example.mydemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class firstService extends Service {

	
	final String tag = "firstService";
	boolean flag = true;//邏輯控制開關
	int count=0;//測試參數
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onCreate()");
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onStartCommand()");
		new Thread(){
			public void run() {
				while(flag){
					System.out.println("進度:"+count++);
					if(count>99){
						flag=false;
					}
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				
			}		
		}.start();;
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onDestroy()");
		flag = false;
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

}
第一個service對應第二種啓動方式:

package com.example.mydemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;


public class secondService extends Service{

	boolean flag = true;	
	final String tag = "secondService";
	int count=0;
	class mybinder extends Binder{
		public int getCount(){
			return count;
		}
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onCreate()");
		super.onCreate();
	}


	//建立契約
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onBind()");
		new Thread(){
			public void run() {
				while(flag){
					System.out.println("進度:"+count++);
					if(count>100){
						flag=false;
					}
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				
			}		
		}.start();
		return new mybinder();
	}

	//解除契約
	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i(tag, tag+"....onUnbind()");
		return super.onUnbind(intent);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		flag = false;
		Log.i(tag, tag+"....onDestroy()");
		super.onDestroy();
	}

}
activity的主函數調用

package com.example.mydemo;

import com.example.mydemo.secondService.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;
import android.widget.Toast;

public class MainActivity extends Activity {

	private mybinder mybinder;
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		//當訪問者與之連接成功時調用
		@Override
		public void onServiceConnected(ComponentName name, IBinder ibinder) {
			// TODO Auto-generated method stub
			mybinder = (com.example.mydemo.secondService.mybinder) ibinder;
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	/**
	 * startService所啓動的服務
	 * 1.它是不受任何人影響的
	 * 2.它是作爲一個單獨的個體存在的,沒有辦法與其他組件之間進行數據交互
	 * @param view
	 */
	public void btn(View view){
		Toast.makeText(MainActivity.this, mybinder.getCount()+"", Toast.LENGTH_LONG).show();
	}
	
	public void btn1(View view){
		unbindService(serviceConnection);
	}
	
	public void btn2(View view){
		Intent intent = new Intent(this,secondService.class);
	//	startService(intent);
		bindService(intent, serviceConnection, BIND_AUTO_CREATE);
	}

	/**
	 * 如果使用bindServiuce啓動的服務,那麼service就與調用者的生命週期就有關聯了,
	 * 所以退出時也要終止service
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unbindService(serviceConnection);
		super.onDestroy();
	}
	
	
	
}
效果就不發了。反正第二種方式所打開的service它的生命週期已經和activity綁定了。
這種方式可以讓我們自定義地暫停和重啓服務。








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