1. 程式人生 > >Android Service完全解析,關於服務你所需知道的一切(上)(筆記)

Android Service完全解析,關於服務你所需知道的一切(上)(筆記)

參考原文:Android Service完全解析,關於服務你所需知道的一切(上)

Service的基本用法

然後新建一個MyService繼承自Service,並重寫父類的onCreate()、onStartCommand()和onDestroy()方法,
可以看到,在Start Service按鈕的點選事件裡,我們構建出了一個Intent物件,並呼叫startService()方法來啟動MyService。然後在Stop Serivce按鈕的點選事件裡,我們同樣構建出了一個Intent物件,並呼叫stopService()方法來停止MyService。程式碼的邏輯非常簡單,相信不需要我再多做解釋了吧。

public class MyService extends Service {
 
	public static final String TAG = "MyService";
 
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "onCreate() executed");
	}
 
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "onStartCommand() executed"
); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy() executed"); } @Override public IBinder onBind(Intent intent) { return null; } }
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:
android
="http://schemas.android.com/apk/res/android" package="com.example.servicetest" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > …… <service android:name="com.example.servicetest.MyService" > </service> </application> </manifest>

Service和Activity通訊

public class MyService extends Service {
 
	public static final String TAG = "MyService";
 
	private MyBinder mBinder = new MyBinder();
 
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "onCreate() executed");
	}
 
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "onStartCommand() executed");
		return super.onStartCommand(intent, flags, startId);
	}
 
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestroy() executed");
	}
 
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}
 
	class MyBinder extends Binder {
 
		public void startDownload() {
			Log.d("TAG", "startDownload() executed");
			// 執行具體的下載任務
		}
 
	}
 
}

如何銷燬Service

那麼如果我們既點選了Start Service按鈕,又點選了Bind Service按鈕會怎麼樣呢?這個時候你會發現,不管你是單獨點選Stop Service按鈕還是Unbind Service按鈕,Service都不會被銷燬,必要將兩個按鈕都點選一下,Service才會被銷燬。也就是說,點選Stop Service按鈕只會讓Service停止,點選Unbind Service按鈕只會讓Service和Activity解除關聯,一個Service必須要在既沒有和任何Activity關聯又處理停止狀態的時候才會被銷燬。

Service和Thread的關係

Service確實是執行在主執行緒裡的,也就是說如果你在Service裡編寫了非常耗時的程式碼,程式必定會出現ANR的。
既然在Service裡也要建立一個子執行緒,那為什麼不直接在Activity裡建立呢?這是因為Activity很難對Thread進行控制,當Activity被銷燬之後,就沒有任何其它的辦法可以再重新獲取到之前建立的子執行緒的例項。而且在一個Activity中建立的子執行緒,另一個Activity無法對其進行操作。但是Service就不同了,所有的Activity都可以與Service進行關聯,然後可以很方便地操作其中的方法,即使Activity被銷燬了,之後只要重新與Service建立關聯,就又能夠獲取到原有的Service中Binder的例項。因此,使用Service來處理後臺任務,Activity就可以放心地finish,完全不需要擔心無法對後臺任務進行控制的情況。

建立前臺Service

public class MyService extends Service {
 
	public static final String TAG = "MyService";
 
	private MyBinder mBinder = new MyBinder();
 
	@Override
	public void onCreate() {
		super.onCreate();
		Notification notification = new Notification(R.drawable.ic_launcher,
				"有通知到來", System.currentTimeMillis());
		Intent notificationIntent = new Intent(this, MainActivity.class);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				notificationIntent, 0);
		notification.setLatestEventInfo(this, "這是通知的標題", "這是通知的內容",
				pendingIntent);
		startForeground(1, notification);
		Log.d(TAG, "onCreate() executed");
	}
 
	.........
 
}

Service幾乎都是在後臺執行的,一直以來它都是默默地做著辛苦的工作。但是Service的系統優先順序還是比較低的,當系統出現記憶體不足情況時,就有可能會回收掉正在後臺執行的Service。如果你希望Service可以一直保持執行狀態,而不會由於系統記憶體不足的原因導致被回收,就可以考慮使用前臺Service。前臺Service和普通Service最大的區別就在於,它會一直有一個正在執行的圖示在系統的狀態列顯示,下拉狀態列後可以看到更加詳細的資訊,非常類似於通知的效果。當然有時候你也可能不僅僅是為了防止Service被回收才使用前臺Service,有些專案由於特殊的需求會要求必須使用前臺Service,比如說墨跡天氣,它的Service在後臺更新天氣資料的同時,還會在系統狀態列一直顯示當前天氣的資訊