日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IntentService详解

發布時間:2024/4/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IntentService详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IntentService是什么?

這篇文章是之前就寫好的,一直沒有整理出來,這幾天有空正好整理發布一下。

我們知道Service可以讓我們在后臺處理一些事情,但是Service實際上也是主線程,所以執行長耗時任務時依然會ANR,只不過ANR觸發時間要比前臺長。一般我們會在Service中開啟一個子線程去完成耗時任務。

而IntentService就是解決這個問題的,它是Service的一個抽象子類,需要實現onHandleIntent,代碼在這個函數中執行。它與Service最大的不同就是默認開啟一個子線程,而onHandleIntent就是在子線程中執行的。

所以IntentService就是一個自帶子線程的Service。

那么它是如何實現的,我們通過它的源碼來簡單分析一下。

線程的創建

IntentService的源碼其實不多,先來看看它的onCreate函數

@Override public void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper); }

在onCreate中會創建并啟動一個HandlerThread。這個HandlerThread是Thread的一個子類,通過它的源碼可以看到實際上就是默認綁定開啟了looper,它的run函數如下:

@Override public void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1; }

可以看到綁定并啟動了一個looper,而它的其他函數則都與looper和handler的操作有關,這里不一一看了。

回到onCreate中,接下來的代碼則是通過HandlerThread的looper創建了一個ServiceHandler,這是一個內部類,源碼如下:

private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);} }

可以看到在handleMessage中調用了onHandleIntent,這樣函數中的代碼就在這個HandlerThread的子線程中運行。

然后執行了stopSelf函數,這個函數是Service的,用于停止服務的,與context的stopService效果是一樣的。

也就是說IntentService執行onHandleIntent后就會試圖停止服務,但是這里還有一些邏輯,注意傳參是msg.arg1,這個很重要,后面會再詳談。

線程運行

通過上面我們知道,IntentService創建時開啟一個線程并啟動一個looper,并且通過ServiceHandler來執行代碼。但是想要執行onHandleIntent,一定需要sendMessage,那么在哪send的呢?

答案是在Service的start周期中,如下:

@Override public void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg); }

可以看到在onStart中組合了一個msg并send,這樣就實現了服務一啟動就自動執行onHandleIntent。
注意msg的arg1參數賦值是startId,結合上面所說的就是執行onHandleIntent后會執行stopSelf(startId)。

上面我們說過stopSelf會試圖停止服務,為什么是試圖而不是一定,關鍵就是startId這里。

只有當stopSelf函數的startId與Service當前的startId相同,才會停止服務,主要是針對多次startService的情況。

當我們多次startService的時候,startId會自動遞增,并且保存最后一個startId。

所以多次startService,onHandleIntent會執行多次,因為前幾次執行到stopSelf時startId不同,只有當最后一個執行完后才真正的停止服務。

但是注意,在onBind函數中并沒有sendMessage,所以IntentService需要使用start的方式,bind的方式由于不會走onStart這個周期,所以onHandleIntent不會執行。

退出線程

在創建線程時默認開啟了looper,looper其實就是一個死循環,所以這個線程會一直阻塞。那么IntentService如何退出這個線程?

總結

以上是生活随笔為你收集整理的IntentService详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。