2019独角兽企业重金招聘Python工程师标准>>>

最近复习到了Handler一直只知道怎么用,却没有仔细分析过源码,这下就来看看

为什么要使用handler呢?

因为在安卓应用中ui操作是线程安全的,只能ui线程去操作ui组件,但是在现实开发中,可能有多个线程去并发操作ui,所以将会导致线程不安全,所以就用到了handler

Looper1.主要负责创建message Queue和自身的创建    2.    消息的循环

public static void prepare() {prepare(true);
}private static void prepare(boolean quitAllowed) {
//判断当前的对象是否为空 ,即prepare不能调用两次if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}创建looper对象放入线程中sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {//looper对象创建了messagequeuemQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();
}

2.looper.loop

public static void loop() {final Looper me = myLooper();if (me == null) {throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");}final MessageQueue queue = me.mQueue;// Make sure the identity of this thread is that of the local process,// and keep track of what that identity token actually is.Binder.clearCallingIdentity();final long ident = Binder.clearCallingIdentity();for (;;) {Message msg = queue.next(); // might blockif (msg == null) {// No message indicates that the message queue is quitting.return;}// This must be in a local variable, in case a UI event sets the loggerfinal Printer logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);}final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;final long traceTag = me.mTraceTag;if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg));}final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();final long end;try {
//吧msg交给msg.target实际就是绑定的handler去处理这个方法中调用了handlemessage所以在创建handler
的时候要重写handlemessage方法msg.target.dispatchMessage(msg);end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();} finally {if (traceTag != 0) {Trace.traceEnd(traceTag);}}if (slowDispatchThresholdMs > 0) {final long time = end - start;if (time > slowDispatchThresholdMs) {Slog.w(TAG, "Dispatch took " + time + "ms on "+ Thread.currentThread().getName() + ", h=" +msg.target + " cb=" + msg.callback + " msg=" + msg.what);}}if (logging != null) {logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);}// Make sure that during the course of dispatching the// identity of the thread wasn't corrupted.final long newIdent = Binder.clearCallingIdentity();if (ident != newIdent) {Log.wtf(TAG, "Thread identity changed from 0x"+ Long.toHexString(ident) + " to 0x"+ Long.toHexString(newIdent) + " while dispatching to "+ msg.target.getClass().getName() + " "+ msg.callback + " what=" + msg.what);}msg.recycleUnchecked();}
}

Looper的作用就是创建message队列,然后吧队列中的消息派发给handler,然后handler去处理消息

然后我们在去看下Handler的源码

public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;
}

可以看出handler创建的时候就会绑定他的looper并找见他的队列

handler有两种发送消息的方法 send和post

public final boolean sendMessage(Message msg)
{return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {msg.target = this;if (mAsynchronous) {msg.setAsynchronous(true);}
//看出来最后调用了队列的方法,也就是handler发出的消息,最后会保存到对应的队列中return queue.enqueueMessage(msg, uptimeMillis);
}

所以就是一个应用的创建,系统会自动给你生成一个主线程,并在这个主线程中生成一个Looper对象来让你和子线程之间进行消息的传递,Looper会创建一个消息队列,当我们在子线程中给主线程发消息的时候就需要用到handler,handler创建的时候就会去找到这个对应的looper。looper不断的执行loop方法去发消息给队列中 ,没当handler去发送一个消息的时候,就吧消息加入到队列中 ,然后队列的loop方法就会接收到这个消息,然后消息去调用dispatchmsg方法,然后dispatchmsg方法就会调用handler中的handlemessage方法,我们就能接收到这个消息

转载于:https://my.oschina.net/u/3234136/blog/1794086

Handler的源码分析相关推荐

  1. Handler机制源码分析

    一.Handler使用上需要注意的几点 1.1 handler使用不当造成的内存泄漏 public class MainActivity extends AppCompatActivity {priv ...

  2. Wangle源码分析:编解码Handler

    2019独角兽企业重金招聘Python工程师标准>>> 前言 编解码是协议相关的,如果没有编解码Handler,那么在处理网络的粘包.拆包时会变得很复杂.除了http之类的公有协议之 ...

  3. Wangle源码分析:Pipeline、Handler、Context

    2019独角兽企业重金招聘Python工程师标准>>> 基本概念 Wangle中的Pipeline和Netty中的Pipeline是很相似的,既可以将它看为一种职责链模式的实现也可以 ...

  4. Android多线程:深入分析 Handler机制源码(二)

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 接下来,深入分析 Handler机制的源码,希望加深理解 目录 1. Handler 机制简介 定义 一套 Android 消 ...

  5. Wangle源码分析:Service

    2019独角兽企业重金招聘Python工程师标准>>> 前言 Wangle中的Service代表一个远程服务(方法),熟悉RPC的朋友肯定知道这就是一个简单的RPC,当然,和一些常见 ...

  6. Wangle源码分析:ClientBootstrap

    2019独角兽企业重金招聘Python工程师标准>>> ClientBootstrap介绍 ClientBootstrap是wangle作为Client端的一个快速启动辅助类,在经过 ...

  7. Wangle源码分析:ServerBootstrap

    2019独角兽企业重金招聘Python工程师标准>>> ServerBootstrap介绍       ServerBootstrap,顾名思义,它是作为Wangle服务端的一个启动 ...

  8. Wangle源码分析:EventBaseHandler、AsyncSocketHandler

    2019独角兽企业重金招聘Python工程师标准>>> 前言 前面的Wangle源码分析系列文章详细的分析了Pipeline.Handler等实现原理,细心的读者可能发现,每次在构造 ...

  9. Handler机制的源码分析

    2019独角兽企业重金招聘Python工程师标准>>> Handler,MessageQueue,Looper的关系 Looper的作用是在线程中处理消息的 MessageQueue ...

最新文章

  1. UWP开发入门(十六)——常见的内存泄漏的原因
  2. oracle数据库实现不同数据库之间的表格数据定期同步
  3. dell服务器怎么查看网卡型号,dell R730集成网卡什么型号
  4. 将数组存入mysql数据库,将数组值写入mysql数据库
  5. 聊聊WebRTC网关服务器1:如何选择服务端端口方案?
  6. Python中is和==的区别
  7. Python练习题和答案
  8. 扫普通二维码打开小程序,可进入体验版
  9. 计算机中显卡在什么地方 看,电脑显卡在哪个位置
  10. 皮皮虾如何去水印视频
  11. 印刷MES管理系统等数字化系统,应用发展如此迅速
  12. PUE 1.2,总投资达36.4亿,17600个机柜!天和防务拟建陕西最大数据中心
  13. 6个不为人知的高质量APP推荐:知乎3万人点赞,2万人收藏!
  14. hadoop 文本统计一个字符的个数_hadoop统计单词个数 - 卡饭网
  15. 笔记本不能用无线网策略服务器,笔记本不能上网的解决方法适用于使用无线路由器上网...
  16. latex(2):公式插入
  17. hust_os_shell算命大师
  18. Linux——LDAP(相当于Windows下的AD)
  19. DISPO与EKGRP 的关系(MRP控制者和采购组)
  20. 机器视觉LED光源照明技术说明

热门文章

  1. 7-48 字符串输入练习 (I) (15 分)
  2. 7-8 菲波那契数列 (15 分)
  3. 7-1 矩阵A乘以B (30 分)
  4. 基于pyQt的按键响应程序,实现按下按键进行图片曝光(按下按钮,运行另一个曝光图片程序.py)
  5. MultipartFile和CommonsMultipartFile的区别!
  6. 模拟ios_王者荣耀策划Donny:安卓IOS今年或实现互通!模拟战一周一更新
  7. linux硬盘系统安装教程图解,Linux操作系统添加安装新硬盘的方法图解
  8. 小郡肝火锅点餐系统——项目文档
  9. 消费者服务消费延时分析
  10. Egret在Chrome浏览器中的内存占用(内存泄露)