中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

不知廬山真面目只緣身在此山中,講解一下Handler

發布時間:2020-03-01 23:08:28 來源:網絡 閱讀:313 作者:Android丶VG 欄目:移動開發

o(╥﹏╥)o今天太困了,啥也不想干。就把之前收集的資料拿出來溫習一下剛好和大家共享下

不知廬山真面目只緣身在此山中,講解一下Handler

之前在" rel="nofollow">GitHub
上更新了些關于面試類的文章,含有從基礎到進階。含有BATJ.字節跳動面試專題,算法專題,高端技術專題,混合開發專題,java面試專題,Android,Java小知識,到性能優化.線程.View.OpenCV.NDK等應有盡有。還有輔之相關的視頻+學習筆記

(更多完整項目下載。未完待續。源碼。圖文知識后續上傳github。)
可以點擊關于我聯系我獲取完整PDF
(VX:mm14525201314)

Handler

1、談談消息機制 Handler 作用 ?

負責跨線程通信,這是因為在主線程不能做耗時操作,而子線程不能更新 UI,所以當子線程中進行耗時操作后需要更新 UI時,通過 Handler 將有關 UI 的操作切換到主線程中執行。

具體分為四大要素:

  • Message(消息): 需要被傳遞的消息,消息分為硬件
    產生的消息(如按鈕、觸摸)和軟件生成的消息。
  • MessageQueue(消息隊列): 負責消息的存儲與管
    理,負責管理由 Handler 發送過來的 Message。讀取
    會自動刪除消息,單鏈表維護,插入和刪除上有優勢。
    在其 next()方法中會無限循環,不斷判斷是否有消息,
    有就返回這條消息并移除。
  • Handler(消息處理器): 負責 Message 的發送及處
    理。主要向消息池發送各種消息事件
    Handler.sendMessage())和處理相應消息事件
    Handler.handleMessage()),按照先進先出執行,
    內部使用的是單鏈表的結構。
  • Looper(消息池): 負責關聯線程以及消息的分發,在
    該線程下從 MessageQueue 獲取 Message,分發給Handler,Looper 創建的時候會創建一個MessageQueue,調用 loop()方法的時候消息循環開始,其中會不斷調用 messageQueue 的 next()方法,當有消息就處理,否則阻塞在 messageQueue 的next()方法中。當 Looperquit()被調用的時候會調用
    messageQueuequit(),此時 next()會返回 null,然
    loop()方法也就跟著退出。

具體流程如下:
不知廬山真面目只緣身在此山中,講解一下Handler

  • 在主線程創建的時候會創建一個 Looper,同時也會在在
    Looper 內部創建一個消息隊列。而在創鍵 Handler 的
    時候取出當前線程的 Looper,并通過該 Looper 對象獲
    得消息隊列,然后 Handler 在子線程中通過MessageQueue.enqueueMessage 在消息隊列中添
    加一條 Message
  • 通過 Looper.loop() 開啟消息循環不斷輪詢調用
    MessageQueue.next(),取得對應的 Message 并且
    通過 Handler.dispatchMessage 傳遞給 Handler,最
    終調用 Handler.handlerMessage 處理消息。
2、一個線程能否創建多個 Handler,Handler 跟 Looper 之間的對應關系 ?
  • 一個 Thread 只能有一個 Looper,一個 MessageQueen,可以有多個 Handler
  • 以一個線程為基準,他們的數量級關系是: Thread(1) :
    Looper(1) : MessageQueue(1) : Handler(N)
3、軟引用跟弱引用的區別
  • 軟引用(SoftReference): 如果一個對象只具有軟引用,則
    內存空間充足時,垃圾回收器就不會回收它;如果內存空間不
    足了,就會回收這些對象的內存。只要垃圾回收器沒有回收
    它,該對象就可以一直被程序使用。
  • 弱引用(WeakReference): 如果一個對象只具有弱引用,那
    么在垃圾回收器線程掃描的過程中,一旦發現了只具有弱引用
    的對象,不管當前內存空間足夠與否,都會回收它的內存。
  • 兩者之間根本區別在于: 只具有弱引用的對象擁有更短暫的生
    命周期,可能隨時被回收。而只具有軟引用的對象只有當內存
    不夠的時候才被回收,在內存足夠的時候,通常不被回收
    不知廬山真面目只緣身在此山中,講解一下Handler
4、Handler 引起的內存泄露原因以及最佳解決方案

為什么會導致泄露:
Handler 允許我們發送延時消息,如果在延時期間用戶
關閉了 Activity,那么該 Activity 會泄露。 這個泄露
是因為 Message 會持有 Handler,而又因為 Java 的
特性,內部類會持有外部類,使得 Activity 會被
Handler 持有,這樣最終就導致 Activity 泄露。

怎么解決:
將 Handler 定義成靜態的內部類,在內部持有
Activity 的弱引用,并在 AcitivityonDestroy()
調用 handler.removeCallbacksAndMessages(null)
及時移除所有消息。

5、為什么系統不建議在子線程訪問 UI?

Android 的 UI 控件不是線程安全的,如果在多線程中并發訪問
可能會導致 UI 控件處于不可預期的狀態

這時你可能會問為何系統不對 UI 控件的訪問加上鎖機制呢?因為:

  • 加鎖機制會讓 UI 訪問邏輯變的復雜
  • 加鎖機制會降低 UI 的訪問效率,因為加鎖會阻塞某些線
    程的執行
    不知廬山真面目只緣身在此山中,講解一下Handler
    6、Looper 死循環為什么不會導致應用卡死?
  • 主線程的主要方法就是消息循環,一旦退出消息循環,那么你的應用也就退出了,Looer.loop()方法可能會引起主線程的阻塞,但只要它的消息循環沒有被阻塞,能一直處理事件就不
    會產生 ANR 異常。
  • 造成 ANR 的不是主線程阻塞,而是主線程的 Looper消息處理過程發生了任務阻塞,無法響應手勢操作,不能及時刷新 UI。
  • 阻塞與程序無響應沒有必然關系,雖然主線程在沒有消息可處理的時候是阻塞的,但是只要保證有消息的時候能夠立刻處
    理,程序是不會無響應的。
7、使用 Handler 的 postDealy 后消息隊列會有什么變化?

如果隊列中只有這個消息,那么消息不會被發送,而是計算到
時喚醒的時間,先將 Looper 阻塞,到時間就喚醒它。但如果此時要加入新消息,該消息隊列的對頭跟 delay 時間相比更長,
則插入到頭部,按照觸發時間進行排序,隊頭的時間最小、隊
尾的時間最大

8丶子線程直接 new 一個 Handler 嗎?怎么做?

不可以,因為在主線程中,Activity 內部包含一個 Looper 對
象,它會自動管理 Looper,處理子線程中發送過來的消息。而
對于子線程而言,沒有任何對象幫助我們維護 Looper 對象,所以需要我們自己手動維護。所以要在子線程開啟 Handler 要先
創建 Looper,并開啟 Looper 循環

9、Message 可以如何創建?哪種效果更好,為什么?

可以通過三種方法創建:

  • 直接生成實例 Message m = new Message
  • 通過 Message m = Message.obtain
  • 通過 Message m = mHandler.obtainMessage()

后兩者效果更好,因為 Android 默認的消息池中消息數量是 10,而后
兩者是直接在消息池中取出一個 Message 實例,這樣做就可以避免多
生成 Message 實例。

請查看完整的PDF版
(更多完整項目下載。未完待續。源碼。圖文知識后續上傳github。)
可以點擊關于我聯系我獲取完整PDF
(VX:mm14525201314)

不知廬山真面目只緣身在此山中,講解一下Handler

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潞西市| 孟州市| 河源市| 汝阳县| 泊头市| 犍为县| 家居| 安庆市| 祁阳县| 阿巴嘎旗| 勃利县| 潼南县| 木里| 泰和县| 长沙市| 衡南县| 陆河县| 肥城市| 东乌珠穆沁旗| 华坪县| 淅川县| 江口县| 咸宁市| 新民市| 大同县| 裕民县| 碌曲县| 什邡市| 罗源县| 元江| 齐河县| 四平市| 三穗县| 林口县| 隆昌县| 神池县| 临颍县| 旬阳县| 贡山| 磴口县| 新巴尔虎右旗|