国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

一定搞懂Handler消息處理機(jī)制系列之「04.Message是如何觸發(fā)的」

2019-11-06 09:37:04
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

Message是如何觸發(fā)的

還是ActivityThread這段代碼。來(lái)自Android中為什么主線程不會(huì)因?yàn)長(zhǎng)ooper.loop()里的死循環(huán)阻塞?

我們知道APP的入口是在ActivityThread,一個(gè)java類,有著main方法,而且main方法中的代碼也不是很多.

public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); SamplingPRofilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); AndroidKeyStoreProvider.install(); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

在上篇文章MessageQueue與Looper的由來(lái)我們得知這段代碼中的Looper.prepareMainLooper()在主線程中創(chuàng)建了一個(gè)Looper對(duì)象,然后在這段代碼的末尾處,調(diào)用了Looper.loop()方法,我們來(lái)看看Looper.loop()源碼

//刪除部分代碼public static void loop() { //獲取當(dāng)前線程的Looper對(duì)象 final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } //獲取Looper對(duì)象中的消息隊(duì)列 final MessageQueue queue = me.mQueue; ... for (;;) { //不斷的從消息隊(duì)列拿出消息隊(duì)列的第一條消息,直到?jīng)]有消息為止 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ... try { msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ... msg.recycleUnchecked(); } }

從這個(gè)loop()方法中邏輯就比較明了了,里面有一個(gè)死循環(huán),從消息隊(duì)列中不斷的取出消息,然后調(diào)用這個(gè)方法msg.target.dispatchMessage(msg)msg.tagre為當(dāng)初你創(chuàng)建的Handler對(duì)象,因?yàn)樵贖andler把消息放入消息隊(duì)列的時(shí)候執(zhí)行了以下代碼:

//Handler類private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }

可以看到這里把創(chuàng)建的Handler賦值給了msg.target。然后msg.target.dispatchMessage(msg)就相當(dāng)于handler.dispatchMessage(msg),所以我們來(lái)看看Handler的dispatchMessage()方法:

public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { //mCallback為當(dāng)初創(chuàng)建Handler時(shí)傳入的Callback對(duì)象 if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } private static void handleCallback(Message message) { message.callback.run(); }

如果看過(guò)第一篇Handler消息發(fā)送我們就可以了解到Handler是如何發(fā)送消息的,所以看到這段代碼就應(yīng)該知道這些消息或者是回調(diào)是如何發(fā)送的了。

根據(jù)自己的理解,繪制了以下流程圖,如有錯(cuò)誤,請(qǐng)及時(shí)提醒我改正:

這個(gè)系列是本人寫(xiě)的第一篇比較完成的博客,肯定會(huì)有非常多的不足,希望大家能夠多留言批評(píng),希望能明確指出文章中可能有的錯(cuò)誤,我會(huì)及時(shí)更正,謝謝。

系列目錄:

一定搞懂Handler消息處理機(jī)制系列之「01.Handler消息發(fā)送」

一定搞懂Handler消息處理機(jī)制系列之「02.Message入列」

一定搞懂Handler消息處理機(jī)制系列之「03.MessageQueue與Looper的由來(lái)」

一定搞懂Handler消息處理機(jī)制系列之「04.Message是如何觸發(fā)的」


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 江川县| 平和县| 平罗县| 百色市| 大理市| 庄河市| 江油市| 元谋县| 洞头县| 黔江区| 楚雄市| 濮阳县| 江津市| 集安市| 工布江达县| 长垣县| 九江市| 和平区| 保靖县| 鄂伦春自治旗| 抚松县| 牡丹江市| 轮台县| 东海县| 白银市| 上虞市| 宁城县| 和田县| 石楼县| 贵德县| 雷山县| 姚安县| 离岛区| 白银市| 罗山县| 安多县| 迁西县| 社会| 大化| 抚松县| 甘泉县|