中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

上海 網(wǎng)站平臺開發(fā)互聯(lián)網(wǎng)營銷師考試題及答案

上海 網(wǎng)站平臺開發(fā),互聯(lián)網(wǎng)營銷師考試題及答案,南京建設(shè)教育網(wǎng)站,wordpress首頁圖標Android HandlerThread、Looper、MessageQueue 源碼分析 簡介 在 Android 開發(fā)中,大家應該對 HandlerThread 有一定了解。顧名思義,HandlerThread 是 Thread 的一個子類。與普通的 Thread 不同,Thread 通常一次只能執(zhí)行一個后臺任務&#x…

Android HandlerThread、Looper、MessageQueue 源碼分析

簡介

Android 開發(fā)中,大家應該對 HandlerThread 有一定了解。顧名思義,HandlerThreadThread 的一個子類。與普通的 Thread 不同,Thread 通常一次只能執(zhí)行一個后臺任務,如果需要執(zhí)行多個任務,就必須創(chuàng)建多個線程,這樣容易導致資源管理復雜,甚至可能出現(xiàn)內(nèi)存泄漏等問題。而 HandlerThread 有一個顯著的特點,它能夠串行地執(zhí)行多個任務。每個任務通過消息的形式排隊執(zhí)行,線程池中的任務按順序依次處理,無需手動管理線程的生命周期或調(diào)度過程。我們只需通過 Handler 將任務發(fā)送到 HandlerThread 中,它會自動按順序執(zhí)行,極大簡化了開發(fā)過程。使用 HandlerThread 的最大優(yōu)勢是:它是單線程的,因此不需要擔心線程安全問題。實際上,Android 源碼中也有許多地方使用了 HandlerThread,它在設(shè)計思想上值得我們學習和借鑒。接下來,我們將通過源碼進一步了解它的實現(xiàn)原理。

源碼分析

HandlerThread內(nèi)部持有一個Looper,Looper中持有一個消息隊列MessageQueue

Looper

在了解HandlerThread前,我們有必要先認識一下Looper,Looper 是一個負責管理消息隊列(MessageQueue)并循環(huán)處理其中消息的類。簡單來說,Looper 通過不斷地從消息隊列中取出消息并處理它們,來實現(xiàn)線程的消息處理機制。每個線程都有自己的消息隊列和 Looper,通過 Looper,線程能夠不斷地處理任務直到任務隊列為空。接下來我們會涉及到它以下幾個核心接口。

  • prepare() 是一個靜態(tài)方法,用來構(gòu)建一個Looper對象,quitAllowed表示這個Looper是否支持退出,默認是支持,像Android 主線程的Looper是不支持退出的
    public static void prepare() {prepare(true);}
  • loopOnce 靜態(tài)方法,顧名思義,循環(huán)一次,它的作用是從當前消息隊列MessageQueue中取一條符合條件的消息進行分發(fā)操作
private static boolean loopOnce(final Looper me,final long ident, final int thresholdOverride) {Message msg = me.mQueue.next(); // 取一條消息if (msg == null) {//正常沒消息,隊列會堵塞,不會返回null,所以這里是null肯定是已經(jīng)要結(jié)束了,這里返回false 退出looperreturn false;}//分發(fā)消息代碼邏輯省略}
  • loop() 靜態(tài)方法,啟動循環(huán),在循環(huán)中不斷調(diào)用loopOnce來處理消息
//關(guān)鍵代碼public static void loop() {final Looper me = myLooper();
//...for (;;) {if (!loopOnce(me, ident, thresholdOverride)) {//返回false 意味著循環(huán)結(jié)束return;}}}
  • quit()quitSafely() 退出looper,前者是立即退出,后者是處理完當前隊列中所有消息后退出,最終是調(diào)用消息隊列MessageQueue對應的退出方法
    public void quit() {mQueue.quit(false);
}public void quitSafely() {mQueue.quit(true);
}

HandlerThread

  • 既然它是一個線程,那可以先從run方法入手:
@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}

可以看出,線程跑起來后,先初始化了一個Looper,然后啟動死循環(huán),HandlerThread在這里充當?shù)淖饔檬窃谧泳€程中開啟死循環(huán)接受和分發(fā)消息
這里有個地方比較有意思,在mLooper = Looper.myLooper();后面,它調(diào)用了notifyAll(),它起到了什么作用呢?

  • getLooper(),我們應該知道要把任務提交給HandlerThread執(zhí)行,需要借助Handler,但是Handler的構(gòu)造參數(shù)是需要傳入一個Looper對象,所以,這里對外公開了獲取Looper的接口
public Looper getLooper() {if (!isAlive()) {return null;}boolean wasInterrupted = false;// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {wasInterrupted = true;}}}/** We may need to restore the thread's interrupted flag, because it may* have been cleared above since we eat InterruptedExceptions*/if (wasInterrupted) {Thread.currentThread().interrupt();}return mLooper;}

這里是直接返回了在run中初始化的mLooper,但是呢,在非當前線程獲取mLooper對象,就會引發(fā)線程安全問題,可能mLooper還沒被初始化就調(diào)用了getLooper(),這樣就有可能返回一個空的數(shù)據(jù)了,所以官方在這里做了while循環(huán),并且使用了wait()堵塞,等待上面run初始化完成后再notifyAll()這里

  • getThreadHandler() 就是公開給外面向當前HandlerThread插入消息的接口,內(nèi)部維護著一個Handler對象
    @NonNullpublic Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}
  • quit()、quitSafely() 同樣,HandlerThread也有退出的方法,其實現(xiàn)也是調(diào)用looper對應的函數(shù)退出

MessageQueue

由于關(guān)于消息分發(fā)邏輯在其他地方講過,這里只要分析退出隊列的邏輯。
它實現(xiàn)了退出和安全退出的方法,這兩個操作有什么區(qū)別呢,請看源碼

  • next() looper每調(diào)用一次loopOnce,內(nèi)部就會調(diào)用messageQueue獲取一條消息
Message next() {//只放關(guān)鍵代碼for (; ; ) {//堵塞,等待消息或者時機合適或主動喚醒nativePollOnce(ptr, nextPollTimeoutMillis);//...//符合分發(fā)條件的 返回這條消息給looperif (msg != null) {//...return msg;} else {// No more messages.nextPollTimeoutMillis = -1;}//...//退出狀態(tài) 則釋放隊列,結(jié)束循環(huán)if (mQuitting) {dispose();return null;}}
}
  • quit()實際邏輯由下面兩個removeAllFutureMessagesLocked和removeAllMessagesLocked函數(shù)執(zhí)行
void quit(boolean safe) {if (!mQuitAllowed) {throw new IllegalStateException("Main thread not allowed to quit.");}synchronized (this) {if (mQuitting) {//如果已經(jīng)給隊列設(shè)置了退出信號,下面的邏輯就不用走了return;}mQuitting = true;//標記當前隊列處于退出狀態(tài),此時不再接受新的消息if (safe) {//安全退出removeAllFutureMessagesLocked();} else {//立即退出removeAllMessagesLocked();}//把隊列的消息標記完成后,喚醒上面next的堵塞位置nativePollOnce,執(zhí)行剩下的退出邏輯nativeWake(mPtr);}
}
//移除所有消息
private void removeAllMessagesLocked() {//mMessages 在這里是隊列的頭Message p = mMessages;while (p != null) {//從頭開始,把所有消息標記為回收狀態(tài)Message n = p.next;p.recycleUnchecked();p = n;}mMessages = null;//隊頭消息置空,next()執(zhí)行時會判斷這個,為空直接退出隊列
}//移除所有未來消息,退出這一瞬間之前提交的消息保留繼續(xù)執(zhí)行
private void removeAllFutureMessagesLocked() {final long now = SystemClock.uptimeMillis();Message p = mMessages;if (p != null) {if (p.when > now) {//隊頭的時間比當前新,說明全是后面新加的,全部回收掉removeAllMessagesLocked();} else {//以下為從消息隊列中找到退出那一瞬間時間一樣的分割點,把分割點前的消息與隊列斷開鏈接Message n;for (;;) {n = p.next;if (n == null) {return;}if (n.when > now) {break;}p = n;}p.next = null;//斷開鏈接,這里把隊列從分割點切斷do {p = n;n = p.next;p.recycleUnchecked();//把所有未來消息標記為回收狀態(tài)} while (n != null);}}
}

從上面可以看出,安全退出時,隊列會把所有未來消息移除掉,并且不再接受新的消息,隊列中剩下的消息會繼續(xù)被looper取,一直到取完為止,然后結(jié)束隊列退出循環(huán),而普通退出就會把隊列中所有消息移除,然后緊接著結(jié)束隊列退出循環(huán)

quit和quitSafely 應用場景有哪些呢

;//把所有未來消息標記為回收狀態(tài)
} while (n != null);
}
}
}


從上面可以看出,安全退出時,隊列會把所有未來消息移除掉,并且不再接受新的消息,隊列中剩下的消息會繼續(xù)被looper取,一直到取完為止,然后結(jié)束隊列退出循環(huán),而普通退出就會把隊列中所有消息移除,然后緊接著結(jié)束隊列退出循環(huán)### quit和quitSafely 應用場景有哪些呢
舉一個簡單的例子,在Android 使用Room操作數(shù)據(jù)庫,由于操作數(shù)據(jù)庫需要在子線程,所以,我們可以構(gòu)造一個`HandlerThread`,專門處理操作數(shù)據(jù)庫的任務,如果操作過程非常耗時,然后又要關(guān)閉數(shù)據(jù)庫,
http://www.risenshineclean.com/news/46367.html

相關(guān)文章:

  • wordpress數(shù)據(jù)庫沒有填寫培訓行業(yè)seo整站優(yōu)化
  • 長安網(wǎng)站建設(shè)軟件開發(fā)北京seo關(guān)鍵詞排名優(yōu)化
  • 網(wǎng)站充值平臺怎么做的推廣平臺下載
  • 網(wǎng)站建設(shè)智能優(yōu)化seo軟件推廣哪個好
  • 詳情頁通用模板北京百度seo
  • 東莞市建設(shè)安監(jiān)局網(wǎng)站互動營銷案例100
  • h5用什么網(wǎng)站來做推廣怎么推
  • 泛解析對網(wǎng)站的影響廈門網(wǎng)站推廣優(yōu)化哪家好
  • 寧波易通寧波網(wǎng)站建設(shè)優(yōu)化落實新十條措施
  • 專門教做甜品的網(wǎng)站微信營銷軟件手機版
  • 建設(shè)網(wǎng)站如何贏利企業(yè)網(wǎng)站cms
  • 廣州 網(wǎng)站開發(fā) 公司電話百度seo優(yōu)化排名
  • dw企業(yè)網(wǎng)站設(shè)計品牌營銷包括哪些內(nèi)容
  • 網(wǎng)站加載效果怎么做的百度推廣代運營
  • wordpress mysql重啟資源網(wǎng)站優(yōu)化排名軟件公司
  • 成華網(wǎng)站制作為什么中國禁止谷歌瀏覽器
  • 標題優(yōu)化方法郴州seo快速排名
  • 今日濮陽重大新聞seo優(yōu)化服務是什么意思
  • asp.net做的網(wǎng)站要放到網(wǎng)上空間去_要放哪些文件上去網(wǎng)站建網(wǎng)站建設(shè)網(wǎng)站
  • 房山新農(nóng)村建設(shè)網(wǎng)站深圳百度seo公司
  • 免費代理ip的網(wǎng)站百度搜索推廣操作簡要流程
  • 如何進行網(wǎng)站運營與規(guī)劃打開百度網(wǎng)頁
  • 國外做批發(fā)配件的 在哪個網(wǎng)站百度葷seo公司
  • 傳奇網(wǎng)站怎么制作教程查關(guān)鍵詞
  • windows做網(wǎng)站服務器杭州推廣公司
  • 什么是網(wǎng)站功能需求推推蛙品牌策劃
  • 有服務器可以做網(wǎng)站嗎站長工具是什么意思
  • 商業(yè)網(wǎng)站建立搜索引擎優(yōu)化seo應用
  • 中國三農(nóng)建設(shè)工作委員會官方網(wǎng)站深圳網(wǎng)絡(luò)推廣最新招聘
  • 云服務器可以做網(wǎng)站嗎網(wǎng)絡(luò)營銷的一般流程