除非我們特別為某個操作指定特定的線程,否則大部分線程都在前臺UI界面上的執行操作。這可能存在某些隱患,因為部分在UI界面上的耗時操作可能會影響界面的響應性能。UI界面的性能問題會容易惹惱用戶,甚至可能導致系統ANR錯誤。為了避免這樣的問題,Android Framework提供了幾個類,用來幫助你把那些耗時操作移動到后臺線程中執行。那些類中最常用的就是IntentService.
IntentService是繼承于Service并處理異步請求的一個類,在IntentService內有一個工作線程來處理耗時操作,啟動IntentService的方式和啟動傳統Service一樣,同時,當任務執行完后,IntentService會自動停止,而不需要我們去手動控制。另外,可以啟動IntentService多次,而每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調方法中執行,并且,每次只會執行一個工作線程,執行完第一個再執行第二個,以此類推。
而且,所有請求都在一個單線程中,不會阻塞應用程序的主線程(UI Thread),同一時間只處理一個請求。
IntentService 優點
1.不需要我們在Service中手動開線程的麻煩
2.當操作完成時,我們不用手動停止Service。
IntentService有下面幾個局限性:
1.不可以直接和UI做交互。為了把他執行的結果體現在UI上,需要把結果返回給Activity。
2.工作任務隊列是順序執行的,如果一個任務正在IntentService中執行,此時你再發送一個新的任務請求,這個新的任務會一直等待直到前面一個任務執行完畢才開始執行。
3.正在執行的任務無法打斷。
使用
1.創建IntentService
public class MyService extends IntentService {
/**
*重寫無參構造函數
*/
public MyService(){
super("test");
}
/**
* 創建一個IntentService。調用子類的構造函數。
*
* @param name 用于命名工作線程, 只有調試情況下使用.
*/
public MyService(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
//任務隊列,此處可以進行耗時操作,并且自動排隊完成
......
......
}
}
2.在Manifest文件中定義IntentService
<service
android:name=".MyService"
android:exported="false"/>
在此<service>標簽并沒有包含任何intent filter。因為發送任務給IntentService的Activity需要使用顯式Intent,所以不需要filter。這也意味著只有在同一個app或者其他使用同一個UserID的組件才能夠訪問到這個Service。
3.創建任務請求并發送到IntentService
例如在Activity中
Intent intent = new Intent(this, DownService.class);
// Bundle bundle = new Bundle();
// bundle.putString("videlURL" , videoUrl);
// bundle.putString("fileName" , fileName);
// intent.putExtras(bundle);
startService(intent);
當startService之后 我們的MyService 會執行onHandleIntent方法,多次點擊會排隊之行該方法。
如果你打印LOG 并重寫 所有的 Service 生命周期方法,你會發現,多次觸發startService(intent)的話,onCreate方法只執行了一次,而onStartCommand方法執行了兩次,開啟了兩個Work Thread,這就證實了之前所說的,啟動多次,但IntentService的實例只有一個,這點跟Service是一致的。