Handler源码分析

时间:2021-7-3 作者:qvyue

MessageQueue:消息队列
用来存放通过Handler发送的消息
它是一个按Message的when排序的优先级队列
Looper:循环器
负责循环取出Message Queue里面的当前需要处理的Message
交给对应的Handler进行处理
处理完后,将Message缓存到消息池中,以备复用

Message:数据载体

Message:重要属性

 public int what;//标识(类似于id)
 public int arg1;//保存int数据
 public int arg2;//保存int数据
 public Object obj;//保存任意数据
 public long when;//记录应该被处理的时间值
 Handler target;//用来处理消息的Handler对象,就是发送消息的handler
 Runnable callback; //用来处理消息的回调器(一般不用)
 Message next;//指向下一个Message,用来形成一个链表
 private static Message sPool; //用来缓存处理过的Message,以便复用
Message obtain() //该方法利用了Message中消息池(sPool)
Runnable的run()什么时候在分线程执行?

将Runnable传给Thread的构造方法:

new Thread(new Runnable(){
    public void run(){//在分线程执行

    }
}).start();
Handler: 发送消息 处理消息 移除消息
public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0);//延迟消息  延迟时间为0
    }


 public final boolean sendEmptyMessage(int what)
    {
        return sendEmptyMessageDelayed(what, 0);//发送一个空的延迟消息
    }

    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {//发送不带数据的消息
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }

    //发送延迟消息,指定消息,指定延迟时间
    public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis 
MessageQueue:存储消息的以message的when排序的优先级队列
boolean enqueueMessage(Message msg, long when){}//将message添加到队列中

  for (;;) { //将当前消息对象保存到消息队列中一个合适的位置 
                    prev = p;
                    p = p.next;
                    if (p == null || when 
Looper 从MessageQueue中获取当前需要处理的消息,并交给Handler处理
 //核心方法
 public static void loop() { 
      final Looper me = myLooper(); //得到looper对象
      final MessageQueue queue = me.mQueue; //得到消息队列对象
     // 无限循环 没有break
     for (;;) { 
      Message msg = queue.next(); // 从消息队列中取出消息  might block(可能阻塞)
      ......
      msg.target.dispatchMessage(msg); //调用Handler去分发并处理消息
      msg.recycleUnchecked(); //回收利用message
      }
}
消息机制与异步任务总结

在Android中,只有在UIThread(主线程)中才能直接更新页面
在Android中长时间的工作(联网)都需要在worker Thread中执行
在分线程获得服务器数据后,需要立即到主线程中去更新界面显示数据

如何实现线程间通讯?

1)消息机制:Handler + Thread
2)异步任务: AsyncTask == Handler + ThreadPool

相关API
Message

Message(消息):线程间通信的数据载体
1) 对象的创建
Message.obtain() //有可能是新建的,也有可能是复用的消息池中的
2)对象的使用
使用相对较频繁的
int what //标识
int args1//存储整形数据
int args2//存储+整形数据
Object obj //存储任意类型(对象)数据
使用不频繁的
Handler target //保存处理消息的handler对象(发消息的handler)
long when //消息应该被处理的时间
Message next //有了此属性Message就可以形成队列
static Message pool //消息池,缓存用过得消息用于复用
Runnable CallBack // 用来处理当前消息的回调器

Handler的使用

Handler // 发送 处理 移除消息
1)对象的创建
new Handler()

  1. 对象的使用
    发送消息
    发即时消息:sendMessage(Message message)
    发延迟消息:sendMessageDelayed(Message message,long delayTime)
    发即时空消息:sendEmptyMessage(int what) //发送内容为空
    发延迟空消息:sendEmptyMessageDelayed(int what,long delayTime)

处理消息
void handleMessage(Message msg) //回调方法

移除消息
removeMessage(int what) //移除未处理的指定what的message
removeCallbacksAndMessages(@Nullable Object token) // 传null【removeCallbacksAndMessages(null)】移除所有未处理的消息

MessageQueue :消息队列

用来存放通过Handler发送的消息
它是一个按Message的when排序的优先级队列

Looper(钩子) 循环器

负责循环取出MessageQueue里面的当前需要处理的Message
交给对应的Handler进行处理
处理完后,将Message缓存到消息池中,以备复用

消息机制的原理
Handler源码分析
image.png
Handler源码分析
image.png
Handler用于做什么工作?

1.线程间通信(子线程切换到主线程运行)
2.延迟的工作
3.循环定时工作

AsyncTask的使用

1.什么是异步任务?
逻辑上:以多线程的方式完成的功能需求
API上:指AscyncTask

AsyncTask的理解

1)在没有它之前我们可以用Handler+Thread实现一个异步任务的功能
2)使用AsyncTask也可以实现异步功能
为什么使用AsyncTask
1.编码简洁(可以理解为填空题(Async)和问答题的区别)
2.运行效率高:线程池
相关API:

Handler源码分析
image.png
Async的基本原理
Handler源码分析
image.png
JSON

1.JSON是什么?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
本质就是具有特定格式的字符串
JSON数据已经是客户端与服务器端交互的最常用的选择,已经很少使用xml来进行数据交互了
json与xml比较的优势:
简洁 小(省流量、响应快)
2.JSON的数据格式
整体结构:
Json数组:[ ]
Json对象:{ }
Jso数组的结构:[value1,value2,value3]
Json对象的结构:{key1:value1,key2:value2,key3:value3}
key的数据类型:字符串
value的数据类型:
数值
字符串
null
json数组[]
json对象{}
例子:

[1,"ab",[],{"n":123,"b":"abc"}]
{"name":"TOM","age":12}
Handler源码分析
image.png

3.如何解析JSON
解析技术:
Android原生API:编程相对麻烦
Gson框架:编码简洁,项目首选
解析方向:
将java对象(包含集合)转换为json格式字符串(服务器)
将json格式字符串转化为java对象(包含集合)

相关API
Handler源码分析
image.png

对象根据Key取value 数组根据下标取值

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。