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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

handler

發布時間:2023/12/25 综合教程 38 生活家
生活随笔 收集整理的這篇文章主要介紹了 handler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

畫圖說明:

我在學習和使用handler的時候,對與它相關的源代碼進行的研究,說到handler機制,就要設計到5個類(畫圖),

Handler、MessageQueue、Looper、Thread、還有一個Message;

Message是消息,它由MessageQueue統一列隊,由Handler處理。

Handler是處理者,他負責發送和處理Message消息。

MessageQueue指消息隊列,它用來存放Handler發送過來的隊列,并且按照先入先出的規則執行。

Looper的作用就像抽水的水泵,它不斷的從MessageQueue中去抽取Message并執行。

Thread線程,是消息循環的執行場所。

知道了這幾個類就可以說說消息機制的原理了,在創建Activity之前,當系統啟動的時候,先加載ActivityThread這個類,在這個類的main函數中,調用Looper.prepareMainLooper()進行初始化Looper對象,然后創建主線程的handler對象,隨后才創建ActivityThread對象,最后調用Looper.loop()方法,不斷的進行輪詢消息隊列中的消息。也就是說,在ActivityThread和Activity創建之前,就已經開啟了Looper的loop()方法,不斷的進行輪詢消息。

我們可以畫圖來說明handler機制的原理:

我們通過Message.obtain()準備消息數據之后,

第一步是使用sendMessage():通過Handler將消息發送給消息隊列

第二步、在發送消息的時候,使用message.target=this為handler發送的message貼上當前handler的標簽

第三步、開啟HandlerThread線程,執行run方法。

4、在HandlerThread類的run方法中開啟輪詢器進行輪詢:調用Looper.loop()方法進行輪詢消息隊列的消息

5、在消息隊列MessageQueue中enqueueMessage(Message msg, long when)方法里,對消息進行入列,即依據傳入的時間進行消息入列(排隊)

6、輪詢消息:與此同時,Looper在不斷的輪詢消息隊列

7、在Looper.loop()方法中,獲取到MessageQueue對象后,從中取出消息(Message msg = queue.next()),如果沒有消息會堵塞

8、分發消息:從消息隊列中取出消息后,調用msg.target.dispatchMessage(msg);進行分發消息

9、將處理好的消息分發給指定的handler處理,即調用了handler的dispatchMessage(msg)方法進行分發消息。

10、在創建handler時,復寫的handleMessage方法中進行消息的處理

11、回收消息:在消息使用完畢后,在Looper.loop()方法中調用msg.recycle(),將消息進行回收,即將消息的所有字段恢復為初始狀態。

12. what帶字段,obj帶數據, 創建方法 new Message 或Message.obtain()

handler機制?即handler的作用

在Android的UI開發中,我們經常會使用Handler來控制主UI程序的界面變化。有關Handler的作用,

我們總結為:與其他線程協同工作,接收其他線程的消息并通過接收到的消息更新主UI線程的內容。

我們假設在一個UI界面上面,有一個按鈕,當點擊這個按鈕的時候,會進行網絡連接,并把網絡上的一個字符串拿下來顯示到界面上的一個 TextView上面,這時就出現了一個問題,如果這個網絡連接的延遲過大,可能是10秒鐘甚至更長,那我們的界面將處于一直假死狀態,而如果這段時間超 過5秒鐘的話,程序會出現異常。

這時我們會想到使用線程來完成以上工作,即當按鈕被按下的時候新開啟一個線程來完成網絡連接工作,并把得到的結果更新到UI上面。但是,這時候又會 出現另一個問題,在Android中,主線程是非線程安全的,也就是說UI的更新只能在本線程中完成,其他線程無法直接對主線程進行操作。

為了解決以上問題,Android設計了Handler機制,由Handler來負責與子線程進行通訊,從而讓子線程與主線程之間建立起協作的橋梁,使Android的UI更新的問題得到完美的解決。接下來ATAAW.COM舉例來詮釋Handler的基本使用方法。

A、Handler的工作原理

一般情況下,在主線程中我們綁定了Handler,并在事件觸發上面創建新的線程用于完成某些耗時的操作,當子線程中的工作完成之后,會對Handler發送一個完成的信號,而Handler接收到信號后,就進行主UI界面的更新操作。

B、Handler與子線程協作實例

1、創建Handler實現類,在主UI所在類中的內部類

1 class MyHandler extends Handler {

2 public MyHandler() {

1 }

1 public MyHandler(Looper L) {

1 super(L);

1 }

1 // 重寫handleMessage方法,接受數據并更新UI

1 @Override

1 public void handleMessage(Message msg) {

2 super.handleMessage(msg);

1 //此處根據msg內容進行UI操作

1 }

1 }

2、子線程的實現

1 class MyThread implements Runnable {

1 public void run() {

1 Message msg = new Message();

1 Bundle b = new Bundle();

1 b.putString("cmd", "update");

1 msg.setData(b);

1 MainActivity.this.myHandler.sendMessage(msg);//通知Handler更新UI

2 }

1 }

通過以上的兩個實現,我們只需要在MainActivity中聲明MyHandler實例對象就可以完成線程之間的通訊和界面的更新操作。

MyHandler myHandler = newMyHandler();

調用流程

Message類的obtain方法

消息隊列順序的維護是使用單鏈表的形式來維護的

把消息池里的第一條數據取出來,然后把第二條變成第一條

if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; sPoolSize--; return m; }

創建Handler對象時,在構造方法中會獲取Looper和MessageQueue的對象

public Handler() {
    ...
    //拿到looper
    mLooper = Looper.myLooper();
    ...
    //拿到消息隊列
    mQueue = mLooper.mQueue;
    mCallback = null;
}

查看myLooper方法體,發現Looper對象是通過ThreadLocal得到的,在查找ThreadLocal的set方法時發現

Looper是直接new出來的,并且在Looper的構造方法中,new出了消息隊列對象

sThreadLocal.set(new Looper());

private Looper() {
    mQueue = new MessageQueue();
    mRun = true;
    mThread = Thread.currentThread();
}

sThreadLocal.set(new Looper())是在Looper.prepare方法中調用的

prepare方法是在prepareMainLooper()方法中調用的

public static final void prepareMainLooper() {
    prepare();
    ...
}

在應用啟動時,主線程要被啟動,ActivityThread會被創建,在此類的main方法中

public static final void main(String[] args) {
    ...
    //創建Looper和MessageQueue
    Looper.prepareMainLooper();
    ...
    //輪詢器開始輪詢
    Looper.loop();
    ...
}

Looper.loop()方法中有一個死循環

while (true) {
    //取出消息隊列的消息,可能會阻塞
    Message msg = queue.next(); // might block
    ...
    //解析消息,分發消息
    msg.target.dispatchMessage(msg);
    ...
}

Linux的一個進程間通信機制:管道(pipe)。原理:在內存中有一個特殊的文件,這個文件有兩個句柄(引用),一個是讀取句柄,一個是寫入句柄

主線程Looper從消息隊列讀取消息,當讀完所有消息時,進入睡眠,主線程阻塞。子線程往消息隊列發送消息,并且往管道文件寫數據,主線程即被喚醒,從管道文件讀取數據,主線程被喚醒只是為了讀取消息,當消息讀取完畢,再次睡眠

Handler發送消息,sendMessage的所有重載,實際最終都調用了sendMessageAtTime

public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
   ...
    //把消息放到消息隊列中
    sent = queue.enqueueMessage(msg, uptimeMillis);
   ...
}

enqueueMessage把消息通過重新排序放入消息隊列

final boolean enqueueMessage(Message msg, long when) {
    ...
    final boolean needWake;
    synchronized (this) {
       ...
        //對消息的重新排序,通過判斷消息隊列里是否有消息以及消息的時間對比
        msg.when = when;

        Message p = mMessages;
        //把放入消息隊列的消息置為消息隊列第一條消息
        if (p == null || when == 0 || when < p.when) {
            msg.next = p;
            mMessages = msg;
            needWake = mBlocked; // new head, might need to wake up
        } else {
            //判斷時間順序,為剛放進來的消息尋找合適的位置
            Message prev = null;
            while (p != null && p.when <= when) {
                prev = p;
                p = p.next;
            }
            msg.next = prev.next;
            prev.next = msg;
            needWake = false; // still waiting on head, no need to wake up
        }
    }
    //喚醒主線程
    if (needWake) {
        nativeWake(mPtr);
    }
    return true;
}

Looper.loop方法中,獲取消息,然后分發消息

//獲取消息隊列的消息
 Message msg = queue.next(); // might block
 ...
//分發消息,消息由哪個handler對象創建,則由它分發,并由它的handlerMessage處理  
 msg.target.dispatchMessage(msg);

message對象的target屬性,用于記錄該消息由哪個Handler創建,在obtain方法中賦值

總結

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

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

主站蜘蛛池模板: 亚洲精品一区二区三区在线观看 | 欧美大肥婆大肥bbbbb | 欧美在线va | 一级成人毛片 | 国产精品视频网站 | 欧美一级片一区 | 激情视频亚洲 | 国产成人免费观看 | 黄色网页入口 | 亚洲欧美成人一区二区 | 伊人天堂在线 | 日本人六九视频 | 亚洲欧美第一页 | 亚洲最大的网站 | 精品人妻一区二区三区四区五区 | 揄拍成人国产精品视频 | 一区二区三区四区免费观看 | 国产一区二区三区在线视频观看 | 日韩三级在线免费观看 | 日韩久久久久久 | 97干干干 | 欧美视频免费在线观看 | 光明影院手机版在线观看免费 | 成人免费看黄 | 麻豆成人91精品二区三区 | 亚洲一区二区三区四区视频 | 国产一级影片 | 精品国产乱码久久久久久88av | 狠狠操人人干 | 成人污污视频 | 久操热| 精品人妻一区二区三区蜜桃 | 狠狠干天天 | 字幕网在线 | 久久蜜臀 | 国产男女啪啪 | 九色丨蝌蚪丨成人 | 日本激情视频网站 | 欧美三级精品 | 在线毛片网站 | 日韩专区在线 | 女同亚洲精品一区二区三 | 国产又粗又爽视频 | 欧美大片黄 | 国模私拍在线 | 三上悠亚久久 | 开心激情播播网 | 永久在线观看 | 亚洲色图美腿丝袜 | 老牛影视av老牛影视av | 涩涩免费网站 | 成人在线免费观看网址 | 亚洲精品成人在线 | 国产精品一区二区三区不卡 | 奇米精品一区二区三区在线观看一 | 久久在线视频 | 69xxxx国产 | 少妇免费毛片久久久久久久久 | 久草青青视频 | 国产美女精品视频国产 | 大尺度av在线 | 97视频国产| 久久久久视 | 日韩一区久久 | 成人涩涩软件 | 狠狠干天天 | 欧洲激情网 | 日韩精品自拍偷拍 | 欧美精品网 | 日韩欧美极品 | 韩国三级在线视频 | 国产精品羞羞答答在线观看 | 天天综合在线观看 | 午夜精品一区二区在线观看 | 色香蕉影院 | 国产精品4| 久久国产人妻一区二区免色戒电影 | 奇米影视999| av手机网站 | a级在线观看视频 | 国产网友自拍视频 | 一集毛片 | 亚洲色偷偷色噜噜狠狠99网 | 亚洲天堂一级 | 91久久国语露脸精品国产高跟 | 成人高清视频免费观看 | 超能一家人电影免费喜剧在线观看 | 蜜桃av网站 | 午夜精品电影 | 欧美一级淫片免费视频魅影视频 | 成人h动漫精品一区二区 | 99久久久无码国产精品 | 91精品91久久久中77777 | 国产无遮挡一区二区三区毛片日本 | 国精产品99永久一区一区 | 91视频免费在线观看 | 苍井空张开腿实干12次 | 国产亚洲欧美日韩高清 | 成人国产一区二区三区精品麻豆 |