當前位置:首頁 » 安卓系統 » android子線程handler

android子線程handler

發布時間: 2024-06-11 04:49:28

A. android handler是在主線程中嗎

Handler對拍頌歷象一般是在主線程中創建的,在子線程中執行耗時操櫻凳作發送消息,推襲搜薦你看這篇博客http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html 講解很清晰

B. Android在子線程用handler發送的消息,主線程是怎麼loop到的

因為你是在主線程創建的handler實例,比如你是這樣實例化handler

然後調用looper.loop();就開始了消息循環。這就是為什麼在主線程發消息住線程還能收到消息的原因。因為發送消息的實例是在主線程實例化的就有了主線程的looper。

C. 能講講Android的Handler機制嗎

Android的Handler機制是通俗講為了互相發消息,一般是子線程給主線程發消息完成相應操作。

安卓中最常見的操作是子線程操作完事後得到數據想更新UI,安卓有規定不允許在子線程中刷新UI,所以Handler出現了。

使用和理解大致步驟。

  1. 創建全局Handler對象handler,然後在主線程中初始化它(一般在oncreate中),把它的handmessage裡面的方法重寫,這個方法是收到子線程發給它的消息後執行的邏輯。

  2. 在子線程中獲取數據,調用handler.sendmessage,把要發的消息放在message中。message會添加到Messagequue(消息隊列中,handler創建就帶的)。

3.對象handler被創建和初始化的時候,系統自動會啟動Handler.looper,也就是一個消息輪詢器,它不斷的去查看有沒有消息進入到Messagequue(消息隊列中),有就取出交給handler的handmessage去處理。//這段邏輯是系統自動執行,理解就行。*純手打,不騙人~~~

D. Android——消息分發機制

什麼是 Handler 機制 ?
Handler 機制是 Android 中用於 線程間通信 的一套通信機制。

為什麼是 Handler ?Handler 機制為什麼被那麼多次的提及 ?
從Android4.0開始,Android 中網路請求強制不允許在主線程中操作,而更新UI的操作則不允許在子線程中執行。當在子線程中執行網路請求,拿到伺服器返回的數據之後,要更新UI。由於系統的要求,勢必會產生一種矛盾:數據在子線程,更新UI要在主線程。此時我們必須要把數據返回到主線程中才行,Handler機制應運而生。

Android 中針對耗時的操作,放在主線程操作,輕者會造成 UI 卡頓,重則會直接無響應,造成 Force Close。同時在 Android 3.0 以後,禁止在主線程進行網路請求。

針對耗時或者網路操作,那就不能在主線程進行直接操作了,需要放在子線程或者是工作線程中進行操作,操作完成以後,再更新主線程即 UI 線程。這里就涉及到一個問題了,在子線程執行完成以後,怎麼能更新到主線程即 UI 線程呢,針對以上問題,就需要用到 Android 的消息機制了,即: Handler, Message, MessageQueue, Looper 全家桶

Handler機制中最重要的四個對象

Handler的構造方法:

Looper :

Handler的使用:

MessageQueue:

Looper.loop()

Handler.dispatchMessage()

handler導致activity內存泄露的原因:
handler發送的消息在當前handler的消息隊列中,如果此時activity finish掉了,那麼消息隊列的消息依舊會由handler進行處理,若此時handler聲明為內部類(非靜態內部類),我們知道內部類天然持有外部類的實例引用,這樣在GC垃圾回收機制進行回收時發現這個Activity居然還有其他引用存在,因而就不會去回收這個Activity,進而導致activity泄露。

假如在子線程執行了耗時操作,這時用戶操作進入了其他的 acitvity, 那麼 MainActivity 就會被內存回收的,但是這個時候發現 Handler 還在引用著 MainActivity,內存無法及時回收,造成內存泄漏。

Handler 防止內存泄漏常見方法:

為什麼通過 Handler 可以把子線程的結果通知或者攜帶給 UI 線程 ?
這里的 Handler 指的是主線程的 Handler ,同時與 Handler 配套的 Looper , MessageQueue 是在 UI 線程初始化的,所以在子線程中調用 Handler 發送消息可以更新 UI 線程。
Looper 在 UI 線程源碼, 在 ActivityThread 類:

E. Android中Handler的主要作用是什麼通俗點,初學。

Handler的使用主要是android中無法在主線程(即UI線程)中訪問網路、無法在子線程中訪問UI線程元素。
一般是在子線程中訪問網路,然後使用Handler發送message通知主線程處理UI更新操作

F. Android Handler那些事兒,消息屏障IdelHandlerANR

Handler 是Android SDK中用來處理非同步消息的核心類,子線程可以通過handler來通知主線程進行ui更新。

備註:本文源碼截圖 基於Android sdk 28

Handler機制 消息發送主要流程如圖

應用程序啟動後,zygote fork一個應用進程後,和普通java程序一樣,程序會首先執行ActivityThread中的main函數。在main函數中,程序首先會創建Looper對象並綁定到主線程中,然後開啟loop循環。(ps:主線程loop循環不能退出)

在prepareMainLooper方法中,最終會創建Looper,MessageQueue對象 以及創建native層MessageQueue對象。

使用Handler.sendMessageXXX或這 postDedayXXX發送消息後,最終會調用到SendMessageAtTime方法中。

然後調用MessageQueue.enqueueMessage將消息存到消息隊列中。

存入消息後,然後通過調用native方法 喚醒主線程進行消息處理。

當應用程序啟動,做完一些必要工作之後,便會開啟Loop循環,除非系統異常,否則該循環不會停止。loop循環中,主要做兩件事,第一,從消息隊列中取消息。第二,進行消息分發處理。

MessageQueue.next() 方法 通過調用 native方法 nativePollOnce(ptr, nextPollTimeoutMillis)實現無消息處理時,進入阻塞的功能。
當nextPollTimeoutMillis 值為0時,該方法會立刻返回;
當nextPollTimeoutMillis 值為-1時,該方法會無限阻塞,直到被喚醒;
當nextPollTimeoutMillis 值大於0時,該方法會將該值設置為超時時間,阻塞到達一定時間後,返回;

在loop循環中 ,通過調用 msg.target.dispatchMessage(msg) 進行消息的分發處理

使用當前線程的MessageQueue.addIdleHandler方法可以在消息隊列中添加一個IdelHandler。

當MessageQueue 阻塞時,即當前線程空閑時,會回調IdleHandler中的方法;

當IdelHandler介面返回false時,表示該IdelHandler只執行一次,

a,延遲執行

例如,當啟動Activity時,需要延時執行一些操作,以免啟動過慢,我們常常使用以下方式延遲執行任務,但是在延遲時間上卻不好控制。

其實,這時候使用IdelHandler 會更優雅

b,批量任務,任務密集,且只關注最終結果

例如,在開發一個IM類型的界面時,通常情況下,每次收到一個IM消息時,都會刷新一次界面,但是當短時間內, 收到多條消息時,就會刷新多次界面,容易造成卡頓,影響性能,此時就可以使用一個工作線程監聽IM消息,在通過添加IdelHandler的方式通知界面刷新,避免短時間內多次刷新界面情況的發生。

在Android的消息機制中,其實有三種消息: 普通消息、非同步消息及消息屏障。

消息屏障 也是一種消息,但是它的target為 null。可以通過MessageQueue中的postSyncBarrier方法發送一個消息屏障(該方法為私有,需要反射調用)。

在消息循環中,如果第一條消息就是屏障消息,就往後遍歷,看看有沒有非同步消息:
如果沒有,則無限休眠,等待被喚醒
如果有,就看離這個消息被觸發時間還有多久,設置一個超時時間,繼續休眠

非同步消息 和普通消息一樣,只不過它被設置setAsynchronous 為true。有了這個標志位,消息機制會對它有些特別的處理,我們稍後說。

所以 消息屏障和非同步消息的作用 很明顯,在設置消息屏障後,非同步消息具有優先處理的權利。

這時候我們回顧將消息添加到消息隊列中時,可以發現,其實並不是每一次添加消息時,都會喚醒線程。
當該消息插入到隊列頭時,會喚醒該線程;
當該消息沒有插入到隊列頭,但隊列頭是屏障,且該消息是隊列中 靠前的一個非同步消息,則會喚醒線程,執行該消息;

調用MessageQueue.removeSyncBarrier 方法可以移除指定的消息屏障

ANR 即 Application Not Response, 是系統進程對應用行為的一種監控,如果應用程序沒有在規定時間內完成任務的話,就會引起ANR。

ANR類型

Service Timeout : 前台服務20s, 後台服務200s

BroadcastQueue Timeout : 前台廣播 10s,後台廣播60s

ContentPrivider Timeout : 10s

InputDispatching Timeout : 5s

比如,在啟動一個服務時, AMS端通過應用進程的Binder對象創建Service, 在scheleCreateService()方法中 會調用到當前service的onCreate()生命周期函數;

bumpServiceExecutingLocked()方法內部實際上會調用到scheleServiceTimeoutLocked()方法,發送一個ActivityManagerService.SERVICE_TIMEOUT_MSG類型消息到AMS工作線程中。

消息的延時時間,如果是前台服務,延時20s, 如果是後台服務,延時200s;

如果Service的創建 工作在 上訴消息的延時時間內完成,則會移除該消息,

否則,在Handler正常收到這個消息後,就會進行服務超時處理,即彈出ANR對話框。

復雜情況下,可能會頻繁調用sendMessage 往消息隊列中,添加消息,導致消息積壓,造成卡頓,

1,重復消息過濾

頻繁發送同類型消息時,有可能隊列中之前的消息還沒有處理,又發了一條相同類型的消息,更新之前的數據,這時候,可以採用移除前一個消息的方法,優化消息隊列。

2,互斥消息取消

在發送消息時,優先將消息隊列中還未處理的信息已經過時的消息 移除,優化隊列

3,隊列優化-復用消息

創建消息時,優先採用之前回收的消息,避免重復創建對象,引起GC

完~
(如果錯誤或不足,望指出, 大家共同進步)

熱點內容
ios手機怎麼玩安卓游戲 發布:2024-11-26 17:08:23 瀏覽:395
sql記錄執行 發布:2024-11-26 17:08:15 瀏覽:8
deb反編譯 發布:2024-11-26 17:04:12 瀏覽:140
ftp站點如何設置 發布:2024-11-26 16:54:48 瀏覽:849
預設存儲器 發布:2024-11-26 16:47:38 瀏覽:14
如何打開雲伺服器的窗口 發布:2024-11-26 16:42:37 瀏覽:844
怎麼自學編程入門 發布:2024-11-26 16:40:58 瀏覽:760
夢幻西遊網頁版腳本輔助神器 發布:2024-11-26 16:39:18 瀏覽:67
登陸社保賬號密碼是什麼 發布:2024-11-26 16:23:03 瀏覽:897
優盾加密軟體 發布:2024-11-26 16:15:52 瀏覽:656