Android——Handler学习笔记

首先看图
在这里插入图片描述
应用启动时的入口是ActivityThread的main函数,即是Java的启动入口main函数。在这个main函数中会创建主线程的Looper,之后在主线程中创建的Handler使用的消息机制都执行于main函数的Looper中,其实其他代码也都是执行在loop中的。Looper.loop()有一个for的死循环不断读取消息进行处理,而mMainLooper是不能调用Looper.quit()或Looper.quitSafely()函数的,所以mMainLooper会不停的读取消息链表的消息然后处理,如果有某种消息处理时间过长就会导致卡顿、ANR等。

消息传递流程

首先是创建Handler,而Handler主要的方法就是sendMessage,它用于将消息保存入队列,等待loop中读取再执行。

消息的实体是Message,它有一个next属性,这是组成链表的结构,属性when表示消息执行时间,由参数delayMillis决定,但因为Handler可以在多线程中执行,所以为了保证多线程执行的唯一性,使用了synchronized进行加锁处理,保证在消息入队列和消息出队列时的唯一性,when只保证了消息的执行顺序,不保证执行时间。

Message.target的类型是Handler,这也是保证消息处理后能原路返回结果,但是这个的存在同时也存在内存泄漏的风险。内存泄漏是因为内部类保持了外部类的引用,导致外部类无法释放。那么使用Handler的时候就需要注意这个了,首先需要清空Message才能释放掉Handler,从而再释放Activity等。也有的解决方法是创建特殊的Handler。

将消息保存到队列是MessageQueue的功能,但其实是Message的结构决定的,根据参数when决定消息压入队列链表的某个位置。
在这里插入图片描述

Looper.loop死循环遍历消息队列,假如队列是空queue.next()会进行休眠等待,直到下个消息的到来。
在这里插入图片描述
主线程的Looper是不能quit的,但是子线程的Looper是可以quit的,也为了节省资源,可以看到它会调用MessageQueue的quit方法将消息队列清空并唤醒Looper,让Looper.loop的死循环的queue.next()返回一个null,从而结束死循环,这样才算是完全释放这个Looper,否则Looper会一直休眠等待。
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值