1. 程式人生 > 其它 >android 列印佇列_Android 非同步處理之IntentService原始碼分析

android 列印佇列_Android 非同步處理之IntentService原始碼分析

技術標籤:android 列印佇列

今天介紹一下IntentService,他和Service其實差不多,只是內部實現了一個HandlerThread,這點我們看原始碼其實就可以知道,IntentService的特性如下:

  1. 啟動的方式和正常的Service一致
  2. 執行完任務之後自動停止
  3. 多次啟動以佇列的形式等待執行

使用起來還是比較簡單的,來看下我寫的這個例子:

public class TaskService extends IntentService {private static final String TAG = "TaskService";private ExecutorService service;public TaskService() {super("TaskService");}@Override public void onCreate() {super.onCreate();Log.i(TAG,"onCreate");if (service == null) {service = Executors.newFixedThreadPool(2);}}@Override protected void onHandleIntent(Intent intent) {//通過執行緒池來執行搜尋任務 service.execute(new Runnable() {@Override public void run() {scanSdcardMusic("/mnt/sdcard/");}});}/** * 搜尋Sdcard中的音樂 */ private void scanSdcardMusic(String path) {File file = new File(path);if (file == null)return;File[] files = file.listFiles();if (files != null) {for (int i = 0; i < files.length; i++) {//是否是資料夾 if (files[i].isDirectory()) {scanSdcardMusic(files[i].getPath());} else {if (files[i].getName().endsWith(".mp3")) {Log.i(TAG,"Music:" + files[i].getName());}}}}}@Override public void onDestroy() {super.onDestroy();Log.i(TAG,"onDestroy");}}

來分析一下這段程式碼,首先是繼承IntentService,需要重寫onHandleIntent並且需要一個有名字的構造引數,這裡我預設寫死了一個super("TaskService"),在onCreate中,我初始化了一個執行緒池newFixedThreadPool,因為我們的任務是搜尋Sdcard上所有的mp3檔案,這屬於IO操作,所有我們需要放線上程中操作,具體來看下onHandleIntent,在裡面開啟了一個執行緒池的任務去搜索sdcard,並且將mp3的名字打印出來,我們看下列印的Log

b82970b66a37ef7dece33427a41fe302.png

在Log中我們可以看到搜尋完後列印了兩個mp3,這個時候任務結束了,則自動停止,走了onDestroy方法,這也很符合他的特性,所以他還是比較滿足於一些非同步獨立的任務,我們來看下他的原始碼。

原始碼分析

他的原始碼比較少,我們來看下:

public abstract class IntentService extends Service {private volatile Looper mServiceLooper;private volatile ServiceHandler mServiceHandler;private String mName;private boolean mRedelivery;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);}} public IntentService(String name) {super();mName = name;} public void setIntentRedelivery(boolean enabled) {mRedelivery = enabled;}@Override public void onCreate() { super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}@Override public void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);} @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) {onStart(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}@Override public void onDestroy() {mServiceLooper.quit();} @Override @Nullablepublic IBinder onBind(Intent intent) {return null;} @WorkerThreadprotected abstract void onHandleIntent(@Nullable Intent intent);

來看下他的onCreate入口,他直接就建立了一個HandlerThread並且以傳入的name作為執行緒名稱,getLooper的操作為單獨的佇列,也就對應了他的佇列特性,並且初始化了一個Handler,然後在他的onStartCommand中執行了onStart方法,這個方法只是傳送了一個訊息給Handler,在handleMessage他就更加簡單了,直接呼叫onHandleIntent,接著再呼叫自身的stopSelf結束任務,可以說IntentService的實現是異常的簡單的:總結出一句話:建立執行緒後傳送Handler執行任務後自動停止

就是這麼簡單,你還有什麼疑問嗎?

感謝你在百忙之中看我的文章,謝謝!

對Android感興趣的可以關注我的公眾號【劉桂林】