溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android處理程序中Handler源碼是什么

發(fā)布時(shí)間:2022-01-12 20:04:11 來(lái)源:億速云 閱讀:131 作者:iii 欄目:移動(dòng)開發(fā)

今天小編給大家分享一下Android處理程序中Handler源碼是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

線程Thread的線程變量ThreadLocal中,存放著這個(gè)線程的Looper;Looper在初始化時(shí),會(huì)新建一個(gè)消息隊(duì)列MessageQueue,之后Looper進(jìn)入一個(gè)死循環(huán),等待從消息隊(duì)列MessageQueue取得消息Message(Looper是消費(fèi)者),沒(méi)有消息時(shí)會(huì)阻塞;

我們程序中的Handler,會(huì)通過(guò)sendMessage或post方法,往MessageQueue中添加消息時(shí),添加的這個(gè)Message,會(huì)記錄他是屬于哪個(gè)Handler發(fā)出的,同時(shí)根據(jù)message.when,決定新添加的這個(gè)Message在Queue中的位置,MessageQueue中只有一個(gè)當(dāng)前的Message,隊(duì)列關(guān)系是通過(guò)Message中的prev,next維護(hù)的,Message是一個(gè)鏈表的節(jié)點(diǎn);

添加消息后,消費(fèi)者Looper取得Message,并調(diào)用建立Message的Hander的dispatchMessage方法。

咋一看好像Handler即sendMessage,又handlerMessage,事情還是只有一個(gè)線程在做事情。

但是后來(lái)想想,明白了這樣設(shè)計(jì)的必要性。

因?yàn)檫@個(gè)***的線程一般而言,都是mainUI線程,如果你有個(gè)可以分成多個(gè)小任務(wù)的任務(wù)要處理,你沒(méi)有使用Handler,直接執(zhí)行,也許系統(tǒng)忙于處理你這個(gè)任務(wù),而無(wú)法及時(shí)響應(yīng)用戶事件,從而導(dǎo)致ANR的拋出。

如果你把你的任務(wù)拆成幾個(gè)小任務(wù),用Handler來(lái)實(shí)現(xiàn),那么系統(tǒng)就可以把你的小任務(wù)推到后面來(lái)處理,抽出時(shí)間來(lái)響應(yīng)用戶操作。

如果真的有大任務(wù),一般式需要另外線程去處理,或者開啟Service。

Android處理程序中Handler源碼是什么

一個(gè)在新線程中使用handler例子,我們來(lái)分析下源碼

Java代碼

new Thread(new Runnable() { @Override public void run() { Handler handler; //1、初始化Looper Looper.prepare(); //2、綁定handler到CustomThread實(shí)例的Looper對(duì)象、定義處理消息的方法 handler= new Handler() { @Override public void handleMessage(Message msg) { } }; // 3、發(fā)送消息 handler.sendMessage(new Message()); handler.post(new Runnable()) handler.obtainMessage(1, "hello").sendToTarget(); //4、啟動(dòng)消息循環(huán) Looper.loop(); } }).start();

1 Java代碼

public static final void prepare() { if (sThreadLocal.get() != null) { // 每個(gè)線程,只能有一個(gè)Looper對(duì)象 throw new RuntimeException("Only one Looper may be created per thread"); } // 如果當(dāng)前線程沒(méi)有Looper,新建一個(gè),構(gòu)造函數(shù)是private的 sThreadLocal.set(new Looper()); } private Looper() { mQueue = new MessageQueue(); // 建立消息隊(duì)列 mRun = true; mThread = Thread.currentThread(); }

2 Java代碼

public Handler(){ mLooper = Looper.myLooper(); // 取得當(dāng)前線程的Looper,如果拋異常 if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; // 取得消息隊(duì)列 mCallback = null; }

3 Java代碼

//不管調(diào)用哪個(gè)方法,最終執(zhí)行的是 public boolean sendMessageAtTime(Message msg, long uptimeMillis){ boolean sent = false; // 取得消息隊(duì)列 MessageQueue queue = mQueue; if (queue != null) { msg.target = this; // 消息發(fā)出著是自己 sent = queue.enqueueMessage(msg, uptimeMillis); // 添加到消息隊(duì)列中 } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; } final boolean enqueueMessage(Message msg, long when) { if (msg.when != 0) { throw new AndroidRuntimeException(msg + " This message is already in use."); } if (msg.target == null && !mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit"); } synchronized (this) { if (mQuiting) { RuntimeException e = new RuntimeException( msg.target + " sending message to a Handler on a dead thread"); Log.w("MessageQueue", e.getMessage(), e); return false; } else if (msg.target == null) { mQuiting = true; } msg.when = when; Message p = mMessages; // 之前沒(méi)有其他消息了,MessageQueue中當(dāng)前消息mMessages 就是傳遞進(jìn)來(lái)的msg if (p == null || when == 0 || when < p.when) {  msg.next = p; mMessages = msg; this.notify(); // 喚醒  } else {  // 之前有其他消息了,將傳遞的msg放到適合的位置,根據(jù)when  Message prev = null;  while (p != null && p.when <= when) {  prev = p;  p = p.next;  }  msg.next = prev.next;  prev.next = msg;  this.notify(); // 喚醒  }  }  return true;  }

4 Java代碼

public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { // 死循環(huán) Message msg = queue.next(); // 當(dāng)隊(duì)列中沒(méi)有消息時(shí)會(huì)阻塞 if (msg != null) { if (msg.target == null) { // 消息沒(méi)有發(fā)送者時(shí),退出消息循環(huán) // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); // 調(diào)用消息發(fā)出者的dispatchMessage,這里msg.target是我們sendMessage的handler msg.target.dispatchMessage(msg); if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); } } } final Message next() { boolean tryIdle = true; while (true) { synchronized (this) { // 沒(méi)有消息的或,會(huì)阻塞 try { if (mMessages != null) { if (mMessages.when-now > 0) { Binder.flushPendingCommands(); this.wait(mMessages.when-now); } } else { Binder.flushPendingCommands(); this.wait(); } } catch (InterruptedException e) { } } } }

以上就是“Android處理程序中Handler源碼是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI