Handler机制原理解析(二)prepare,loop,post

上一篇已经介绍了Handler机制的原理,如果不熟悉可以看Handler机制原理解析(一)。这一篇,介绍下Handler周边的知识点。我们已经知道,要获得looper对象,必须要先执行prepare。

1,Looper.prepare

    public static void prepare() {prepare(true);}private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}/*** Initialize the current thread as a looper, marking it as an* application's main looper. The main looper for your application* is created by the Android environment, so you should never need* to call this function yourself.  See also: {@link #prepare()}*/public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}}

从prepareMainLooper的注释我们能看到,初始化当前线程为looper,并且标记为应用的主looper,这个主looper是Android帮忙创建的,所有不需要手动调用。我们跟踪这个方法。在ActivityThread中我们看到

public static void main(String[] args) {....Looper.prepareMainLooper();....Looper.loop();....
}

这里我们只需知道,这个方法会在创建应用的时候调用,并且在主Activity的onCreate前已经调用了即可。至于Activity的启动流程,这里不做详述。这里我们同时也看到了另外一个方法,loop。需要注意的是,如果想在工作线程使用Handler,需要手动调用这两个方法,至于顺序,相信你一定知道。

2,post(Runnable)

    public final boolean post(Runnable r){return  sendMessageDelayed(getPostMessage(r), 0);}

只有这一句,接着看吧,先看getPostMessage

    private static Message getPostMessage(Runnable r) {Message m = Message.obtain();m.callback = r;return m;}

这里将Runnable对象r封装进Message对象了。后面就不用再分析了,因为现在已经变成了send(message),前面我们说过,最终都会调用到一个方法上。发送是相同的,可是处理是不同的。还是贴一下处理的代码吧

    public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}

如果是发送的runnable,则会走第一个分支

    private static void handleCallback(Message message) {message.callback.run();}

这里也没啥,就是让其run起来。再回顾一下,无论在哪个线程post一个Runnable,最终都是会通过dispatch方法,让其run起来,而我们知道,dispatch方法是在主线程。那么View的post方法呢,应该也是封装了Handler的post吧,我们一起看看

    public boolean post(Runnable action) {final AttachInfo attachInfo = mAttachInfo;if (attachInfo != null) {return attachInfo.mHandler.post(action);}// Postpone the runnable until we know on which thread it needs to run.// Assume that the runnable will be successfully placed after attach.getRunQueue().post(action);return true;}

先看第一个分支,如果有attachinfo,就通过handler post出去。这个应该跟handler的方法一样。

        /*** A Handler supplied by a view's {@link android.view.ViewRootImpl}. This* handler can be used to pump events in the UI events queue.*/final Handler mHandler;

看一下Handler,果然一样。这种是view已经attach到window上了,如果没有呢?看另一个分支

    public void post(Runnable action) {postDelayed(action, 0);}public void postDelayed(Runnable action, long delayMillis) {final HandlerAction handlerAction = new HandlerAction(action, delayMillis);synchronized (this) {if (mActions == null) {mActions = new HandlerAction[4];}mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);mCount++;}}

这里还是不清楚,继续往下看

    public static <T> T[] append(T[] array, int currentSize, T element) {assert currentSize <= array.length;if (currentSize + 1 > array.length) {@SuppressWarnings("unchecked")T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>) array.getClass().getComponentType(), growSize(currentSize));System.arraycopy(array, 0, newArray, 0, currentSize);array = newArray;}array[currentSize] = element;return array;}

这里能看明白,就是把handlerAction加入到数组中了(Runnable封装在handlerAction中)。这似乎也没得到执行啊。确实

,没办法,既然有post方法,我们姑且尝试看看有没有handle什么之类名字的方法吧。

    public void executeActions(Handler handler) {synchronized (this) {final HandlerAction[] actions = mActions;for (int i = 0, count = mCount; i < count; i++) {final HandlerAction handlerAction = actions[i];handler.postDelayed(handlerAction.action, handlerAction.delay);}mActions = null;mCount = 0;}}

果不其然,能executeAction,并且通过handler post出去了,猜测应该没问题,那就往上找找看吧。在View的dispatchAttachedToWindow中调用的

        if (mRunQueue != null) {mRunQueue.executeActions(info.mHandler);mRunQueue = null;}

哦,原来当view被attach到window上时,就可以通过handler post出去了。其实呢,跟View post方法的第一个分支一样,只不过保证view一定要执行过attach。

Handler机制原理解析(二)prepare,loop,post相关推荐

  1. Handler机制原理解析(一)

    Handler机制原理解析(一) 我们都知道,在Android中,主线程也叫UI线程是负责界面更新的,子线程或者工作线程适合做网络请求,数据库等耗时操作.如果在主线程中执行耗时操作可能引发ANR异常. ...

  2. android Handler机制原理解析(一篇就够,包你形象而深刻)

    首先,我将Handler相关的原理机制形象的描述为以下情景: Handler:快递员(属于某个快递公司的职员) Message:包裹(可以放置很多东西的箱子) MessageQueue:快递分拣中心( ...

  3. AsyncTask机制原理解析

    AsyncTask机制原理解析 Android为我们提供了2种方便的异步处理方案,Handler和AsyncTask,两种方式适合的场景网上一搜就知道了,但是为什么呢?这篇分析将为你揭晓答案.前面分析 ...

  4. Binder通信机制原理解析

    Binder是什么?Binder有啥用?作为一个应用开发者,如果我们开发的应用不涉及跨进程通信(IPC),我想我们也不会去接触Binder.但不知你有没有发现,近来的Andorid面试,都会问及And ...

  5. OkHttp原理解析(二)

    前言 上一篇我们学习了OKHttp的请求执行流程,知道了最终请求流程都会交给getResponseWithInterceptorChain方法来执行,接下来我们就详细分析执行getResponseWi ...

  6. python解析原理_Python语法垃圾回收机制原理解析

    一 引入 解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那 ...

  7. Android实战开发Handler机制深度解析

    本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助. 本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/gedu ...

  8. RCU锁机制原理解析

    背景 为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁(rwlock),它们使用起来非常简单,而且是一种很有效的同步机制,在UNIX系统和Linux系统中得到了广泛的使用.但是 ...

  9. Hadoop的HA机制原理解析,与HA高可用集群环境搭建

    2019独角兽企业重金招聘Python工程师标准>>> Hadoop的HA工作机制示意图 下面我们开始搭建这一套高可用集群环境 hadoop2.0已经发布了稳定版本了,增加了很多特性 ...

最新文章

  1. 监控系统 Prometheus 和 Zabbix 对比
  2. java vector 输出_5.7(java学习笔记)Vector、Enumeration
  3. 网易有道上市首日股价跌26% 市值达14亿美元
  4. 蘑菇车联打造一体化解决方案,致力产业协同发展
  5. java知识总结-13
  6. 【经典精读】Transformer模型深度解读
  7. 互联网公司客户如何选择短信平台或短信通道需要知道的基本知识
  8. Python如何自动播放视频(XXT)
  9. Java Web课程设计
  10. nacg python证书_这个nacg证书有用吗?
  11. CS224n_2019_Assignment1: Exploring Word Vectors Coding Solution
  12. 数字签名(RSA签名、ElGamal签名、Schnorr签名、DSS、DSA、离散对数签名、特殊性质的签名算法、Chaum盲签名、Chaum-Antwerpen不可否认签名、群签名、MUO代理签名)
  13. 二氧化硅改性活性炭|SiO2改性的V2O5-MoO3/TiO2催化剂|SiO2改性MCM-22分子筛上联苯|纳米SiO2改性环氧涂层海洋腐蚀规律
  14. 换三张麻将源代码php,理论先行:麻将换三张攻略大全
  15. 手机便签内容怎么分享到微博上?
  16. 【时序列】时序列数据如何一步步分解成趋势(trend)季节性(seasonality)和误差(residual)- 详细理解python sm.tsa.seasonal_decompose
  17. 找了三个月,没找到工作 。
  18. 虚拟机使用主机代理(kali v2ray)
  19. 第一个Vant的demo
  20. 计算机推演未来发展动象,信息分析方法复习题

热门文章

  1. php给二维数组加值,php给数组赋值(二维数组赋值)详解
  2. IOCP之AcceptEx的问题(1)
  3. 推荐系统-用户标签预测算法基础实践-决策树(一)
  4. Zjh游戏(十一)注册功能的实现
  5. C#中使用ManagementClass获取本机信息
  6. scrm客户关系管理系统到底是如何发挥作用的?
  7. DXP三种网络去除方式的区别
  8. 什么是4G LTE?移动通信网络知识普及
  9. 【Android Gradle 插件】Android 依赖管理 ④ ( 常用依赖配置分析 | implementation 依赖作用 | api 依赖作用 | compileOnly 依赖作用 )
  10. 211安徽大学大数据与统计学院成立!安徽省属高校首家!