在Android
的四大組件中,Service
排行老二,在Android
中的主要做用是後臺服務,進行與界面無關的操做。因爲Service
運行在主線程,因此進行異步操做須要在子線進行。爲此Android
爲咱們提供了IntentService
。 IntentService
是一個抽象類,繼承至Service
,主要方便咱們新建工做線程進行異步操做。提交任務到IntentService
時,異步任務以串行方式進行處理,意味着工做線程一次只處理一個任務。並且當全部任務都完成以後,會自動中止Service
,不須要咱們手動中止。android
DownloadService
類並繼承至IntentService
。來模擬網絡下載的過程。public class DownloadService extends IntentService {
private static int count = 0;
/**
* 主要用於調用服務類構造器
*
* @param name 用於區分不一樣任務
*/
public DownloadService(String name) {
super(name);
}
/**
* AndroidManifest.xml配置清單須要配置
*
* @param
*/
public DownloadService() {
super("action");
}
/**
*主要重寫該方法,在該方法內進行異步操做。
**/
@Override
protected void onHandleIntent(Intent intent) {
Log.i("Download", "onHandleIntent" + count);
count++;
String name = intent.getStringExtra("action");
if (name.equals("download")) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
Log.i("Download", "download:" + count);
}
}
}
//如下方法的重寫,僅僅爲了打印日誌
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Download", "onDestroy");
}
@Override
public void onCreate() {
super.onCreate();
Log.i("Download", "onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i("Download", "onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Download", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
}
複製代碼
DownloadService
。<service android:name=".DownloadService"/>
複製代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent(this,DownloadService.class);
for (int i =0;i<3;i++){
intent.putExtra("action","download");
intent.putExtra("count",""+i);
startService(intent);
}
}
複製代碼
分析: 從運行結果知道,IntentService
在運行多個任務狀況下,只調用一次onCreate
,調用屢次onStartCommand
,跟Service
的生命週期一致。但,只有在運行完download:1
以後纔會去運行download:2
,接着是download:3
。最後全部任務結束後會自動調用onDestroy
,中止服務。在這裏須要注意的是,和Service
並不一樣,Service
須要咱們手動中止服務。對於結果的回調,能夠採用接口回調,廣播,EventBus
。bash
那麼,IntentService
是如何在Service
中實現異步操做和串行處理任務的呢?網絡
@Override
public void onCreate() {
super.onCreate();
//分析一
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
分析二
mServiceHandler = new ServiceHandler(mServiceLooper);
}
複製代碼
分析一異步
HandThread
繼承Thread
,經過start
方法建立工做線程,內部創建Looper
來達到消息循環,經過Hanlder
消息機制來達到串行的效果和處理多任務。HandThread
和Handler
消息機制,能夠另外查看文章。ide
分析二oop
ServiceHandler
繼承Handler
,與普通的Handler
並無區別,在其內容處理handleMessage
。即調用IntentService
的onHandleIntent
;post
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
複製代碼
Activity
中重複調用startService
方法時,只會屢次調用onStartCommand
方法,並不會重複調用onCreate
方法。咱們看看onStartComamnd
方法的實現。@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
複製代碼
能夠看得出,調用了onStart
方法了。而onStart方法只是將咱們的Intent包裝成Message,經過Handler發送出去,並在Handler中進行處理,調用咱們的onHandleIntent
。進而調用咱們實現onHandleIntent
的代碼。ui
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
複製代碼
IntentService
並無什麼的新的技術含量,在瞭解HandlerTread和Handler的消息機制下,對Handler+Thread+Service
做一個封裝,更適合咱們後臺進行異步耗時操做的場景。有效避免經過new
多個Thread
。this
知識點分享spa