【第八关】Android Handler详解

参考:https://www.jianshu.com/p/9fe944ee02f7
https://www.jianshu.com/p/69b550cb7d43
https://www.jianshu.com/p/3855e0aa7900

Handler是什么

  • Handler是一个消息分发对象。handler是Android给我们提供用来更新UI的一套机制,也是一套消息处理机制,我们可以发消息,也可以通过它处理消息。简单定义为一套Android消息传递机制
  • 1:To schedule messages and runnables to be executed as some point in the future 定时任务
    2:To enqueue an action to be performed on a different thread than your own 在不同线程中执行任务

Handler作用

在多线程的应用场景中,将工作线程中需要跟新UI的操作信息传递到UI主线程,从而实现工作线程对UI的更新处理,最终事项异步消息的处理
在这里插入图片描述

为什么要使用Handler?

  • 最根本的目的就是为了解决多线程并发的问题(多个线程并发更新UI的同时,保证线程安全),将工作线程需操作UI的消息传递到主线程,使得主线程可根据工作线程的需求更新UI,从而避免线程操作不安全的问题

在这里插入图片描述

  • 打个比方,如果在一个activity中有多个线程,并且没有加锁,就会出现界面错乱的问题。但是如果对这些更新UI的操作都加锁处理,又会导致性能下降。处于对性能的问题考虑,Android给我们提供这一套更新UI的机制我们只需要遵循这种机制就行了。不用再去关系多线程的问题,所有的更新UI的操作,都是在主线程的消息队列中去轮询的。
  • 它把消息发送给Looper管理的MessageQueue,并负责处理Looper分发给他的消息

相关概念

  • 在这里插入图片描述
  • Handler类包含如下方法用于发送,处理消息
    • void handleMessage(Message msg):处理消息的方法。通常用于被重写
    • final boolean hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息
    • final boolean hasMessages(int what, Object object):检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。
    • 多个重载的Message obtainMessage():获取消息。
    • sendEmptyMessage(int what):发送空消息。
    • final boolean sendEmptyMessageDelayed(int what, long delayMillis):指定多少毫秒后发送空消息。
    • final boolean sendMessage(Message msg):立即发送消息。
    • final boolean sendMessageDelayed(Message msg, long delayMillis):指定多少毫秒后发送消息。((经验证,该时间为活动onResume时到handleMessage之间的时间))
  • Message:Handler接收和处理的消息对象
    • 2个整型数值(arg1,arg2):轻量级存储int类型的数据
    • 1个Object:任意对象
    • replyTo:线程通信时使用
    • what:用户自定义的消息码,让接收者识别消息
  • MessageQueue:Message队列
    • 采用先进先出 的方式管理Message
    • 每一个线程最多可以拥有一个
  • Looper:消息泵,是MessageQueue的管理者,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理
    • 每个线程只有一个Looper
    • Looper.prepare():为当前线程创建Looper对象
    • Looper.myLooper():可以获得当前线程的Looper对象
  • Handler:能把消息发送给MessageQueue,并负责处理Looper分给它的消息

核心类

Handler机制中有3个重要的类:

  • 处理器类(Handler)
  • 消息队列类(MessageQueue)
  • 循环器类(Looper)

类图在这里插入图片描述
具体介绍:
在这里插入图片描述

工作原理

Handler 机制得到工作流程主要包括4个步骤:

  1. 异步通信准备
  2. 消息发送
  3. 消息循环
  4. 消息处理
  • 具体如下图:
    在这里插入图片描述
  • 工作流程图
    在这里插入图片描述
    • 在这里插入图片描述
    • 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待
    • Android消息处理机制主要是指Handler的运行机制,Handler运行需要底层的MessageQueue和Looper支撑。其中MessageQueue采用的是单链表的结构(先进先出),Looper可以叫做消息循环。由于MessageQueue只是一个消息存储单元,不能去处理消息,而Looper就是专门来处理消息的,Looper会已无限循环的形式去查找是否有新消息,如果有的话,就处理,否则就线程阻塞,等待着
    • Handler创建的时候会采用当前线程的Looper来构造消息循环系统, :线程默认是没有Looper的,如果需要使用Handler就必须为线程创建Looper,因为默认的UI主线程,也就是ActivityThread,ActivityThread被创建的时候就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。
  • 示意图
    在这里插入图片描述
  • 注意
    线程(Thread),循环(Looper),处理者(Handler)之间的对应关系如下:
    • 1个线程(Thread)只能绑定1个循环器(Looper),但可以由多个处理器(Handler)
    • 1个循环器(Looper)可绑定多个处理者(Handler)
    • 1个处理者(Looper)只能绑定1个循环器(Looper)
      在这里插入图片描述

    使用步骤

    • 方式1:使用Handler.sendMessage()
      在该使用方式中,又分为两种:新建Handler子类(内部类),匿名Handler子类,但本质相同,即继承了Handler类&创建了子类
      /** 
      	  * 方式1:新建Handler子类(内部类)
      	*/
      
          // 步骤1:自定义Handler子类(继承Handler类) & 复写handleMessage()方法
          class mHandler extends Handler {
             
      
              // 通过复写handlerMessage() 从而确定更新UI的操作
              @Override
              public void handleMessage(Message msg) {
             
               ...// 需执行的UI操作
                  
              }
          }
      
          // 步骤2:在主线程中创建Handler实例
              private Handler mhandler = new mHandler();
      
          // 步骤3:创建所需的消息对象
              Message msg = Message.obtain(); // 实例化消息对象
              msg.what = 1; // 消息标识
              msg.obj = "AA"; // 消息内容存放
      
          // 步骤4:在工作线程中 通过Handler发送消息到消息队列中
          // 可通过sendMessage() / post()
          // 多线程可采用AsyncTask、继承Thread类、实现Runnable
              mHandler.sendMessage(msg);
      
          // 步骤5:开启工作线程(同时启动了Handler)
          // 多线程可采用AsyncTask、继承Thread类、实现Runnable
      
      	/*
      	*方式2:新建匿名内部类
      	*/
      	// 步骤1:在主线程中 通过匿名内部类 创建Handler类对象
          private Handler mhandler = new  Handler(){
             
              // 通过复写handlerMessage()从而确定更新UI的操作
              @Override
              public void handleMessage(Message msg) {
             
                      ...// 需执行的UI操作
                  }
          };
      
      	  // 步骤2:创建消息对象
      	  Message msg = Message.obtain(); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值