Android的Handler基本原理源码分析

一、前言

学习Android基础知识,都离不开handler,最开始最基础的使用从Handler.post去发送一个消息,Android系统的设计中,为了保证UI渲染的一致性(本质上线程并发问题)和无卡顿体验。耗时的操作需要放在工作线程中执行(一般是开发者自行创建的子线程)、Ui更新放在主线程。这样从各自职责上来讲是非常清晰的,Handler的出现的一个核心目的,就是解决工作线程处理的数据如何传递给Ui线程进行使用。

**故而,**我们在研发中,子线程比如做耗时数据处理操作后,调用通过主线程创建的Handler发送数据消息,最终并由当前的Hander处理消息,实现子线程数据切换到主线程处理的逻辑。

这边文章内容,会深入去理解Android中的Handler机制。先列出这篇文章要解答分析的一个问题列表如下:

  • Handler死循环为什么不会导致应用程序卡死?[答案在3.3节]
  • MessageQueue的优先级队列是如何进行排序的?[答案在2.1节]
  • Message的数据结构是什么?如何保证线程安全的?[答案在2.1节]
  • 如何创建Message对象?【答案在3.1节】
  • 一个线程有几个Handler?如何实现这个机制的?[答案在2.2.3节]
  • 为什么主线程可以直接new Handler进行使用,子线程中new Handler如何操作?[答案在2.2.3节]
  • 为什么Handler容易出现内存泄漏?【答案在3.2节】
  • Handler、Looper、MessageQueue、message之间的关系?【答案在4节】

接下来的文章内容,会从Handler的知识体系的三条主线问题进行展开

  1. Handler的请求发送到哪里去了?
  2. Handler的请求是如何被处理的?
  3. Handler,Looper,MessageQueue、Message之间的关系?

注:文章中涉及到的framework层的源码版本为android29!!!

二、原理源码解析

2.1Handler请求发送

首先我们还是从一个最简单的Demo入手

public class MainActivity extends AppCompatActivity {
   
    private static final int HANDLER_FLAG = 666;

    private Handler mHandler = new Handler() {
   
        @Override
        public void handleMessage(@NonNull Message msg) {
   
            super.handleMessage(msg);

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        //此处通过handler发送一个空消息
        mHandler.sendEmptyMessageDelayed(HANDLER_FLAG, 1000);
    }
}

handler发送消息的方法有多个,如sendMessageDelayed、sendMessage、sendEmptyMessage等,追踪源码最终都会调用到Handler中的sendMessageAtTime():

public class Handler {
   
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
   
        //构建Message对象,通过Message.obtain()获得
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }
    /**
     * 根据绝对时间将message加入到message queue中.
     * @param uptimeMillis 消息被分发的绝对时间     
     * @return Returns true 消息被成功的入队,表示之后将被执行。如果未执行前,looper退出,则
     * 消息终止执行。
     */
    public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
   
      //获取到了主线程的Message queue 后文会有对mQueue的创建分析  
      MessageQueue queue = mQueue;
        //queue为空的异常处理
        if (queue == null) {
   
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
    
    private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
   
        msg.target = this
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hymKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值