Android主线程消息循环简介

主线程消息循环简介

主线程就是ActivityThread,在ActivityThread的main方法中,新建了Looper并开启了Looper循环。循环开启后,每当有新消息进入,Looper会处理对应的消息,处理完后进入休眠状态,主线程的一系列操作都是在这种循环中完成的,这就是主线程的消息循环。

Handler运行机制
  • 什么是Handler

    Handler在日常开发中,我们经常会接触到,通常会用来在非UI线程中调用,用来通知主线程进行一些UI操作。这其实只是Handler的一个使用场景。

    其实Handler是Android消息机制的上层接口,使用Handler可以方便的将一个任务切换到Handler所在的线程中去执行,所以Handler并不是专用来更新UI的,更新UI只是Handler的一个使用场景。

  • Handler、MessageQueue和Looper是如何配合运行的

    Android的消息机制主要是指Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作过程,这三者实际上是一个整体,只不过我们在开发过程中,比较多的接触到Handler而已。

    这里说一下Handler的工作原理:

    • Handler创建时候,会采用当前线程的Looper来构建内部的消息循环系统,如果当前线程没有Looper则会抛出异常。所以Handler需要在有Looper的线程中运行。
    • 如果当前线程没有Looper,我们需要创建。创建Looper的方法包括prepare()prepareMainLooper(),其中第二个方法是主线程专用的创建Looper方法
    • Looper创建完成后,就可以开始消息循环了。每当有新的消息时候,会调用Handler的post方法,实际上post最后调用Handler的send方法,该方法会向MessageQueue中加入一条数据。
    • Looper会不断的轮询MessageQueue中的next()方法,当上一步中有数据加入后,next方法会返回新加入的数据,Looper获取到数据后,回调Handler的disPathMessage方法。
    • 因为Handler会在Looper所在的线程中运行,所以至此实现了切换一个任务到Handler所在线程执行的操作。
主线程循环为什么不会卡死
  • 首先说一下为什么Android要采用消息循环的机制来设计UI线程。

    因为在系统运行中,最小单位是线程,当一个线程运行结束后,系统会销毁对应线程。而UI线程需要一直运行,为了保持线程的活力,所以采用死循环的方式来启动UI线程

  • 死循环是否过于消耗CPU资源?

    主线程的死循环是基于消息队列机制,当MessageQueue没有消息时候,主线程都处于休眠状态,直到下一个消息到达。在休眠装态时候,并不消耗CPU资源。所以只要不在主线程上进行大量的耗时操作,是不用担心主线程一直占用CPU而使应用卡死的。

普通点击事件中的消息逻辑
  • 事件分发之前的操作

    • 在点击事件分发之前,其实屏幕的物理点击操作是通过Handler消息机制来传递给主线程的

    • 每个Activity都实现了一个特殊的接口Window.Callback

    • 在Activity的attach方法中,会通过setCallback方法,使window持有Activity对象

    • 在Activity启动以后,在它的onResume以后,DecorView才开始attahc给WindowManager,从而显示出来。在这个过程中会创建ViewRootImpl,在ViewRootImpl的setView中,会通过跨进程的方式向WMS发起一个调用,从而将DecorView最终添加到Window上,在这个过程中,ViewRootImpl、DecorView和WMS会彼此关联,同时会创建InputChannel、InputQueue和WindowInputEventReceiver来接收点击事件的消息。

    • 点击时候,首先会调用ViewRootImpl.dispatchInputEvent()方法,此方法实现效果如下:

      public void dispatchInputEvent(InputEvent event, InputEventReceiver receiver) {
              SomeArgs args = SomeArgs.obtain();
              args.arg1 = event;
              args.arg2 = receiver;
              Message msg = mHandler.obtainMessage(MSG_DISPATCH_INPUT_EVENT, args);
              msg.setAsynchronous(true);
              mHandler.sendMessage(msg);
          }
      
    • 此处可以看出,通过mHandler发出一个消息,这个消息会通过一系列循环的调用,调到DecorView的dispatchTouchEvent方法,这个方法会获取callback对象,而Activity实现了Callback接口,至此消息传递到Activity

    • 具体的Event传递过程可以参考大神任玉刚的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值