我爱编程

Handler 小结

2018-04-15  本文已影响0人  E_Kwong

Handler 学习

在Android系统中,Handler 是常用的异步消息机制。最近在改项目中Lint出来的问题,顺便查了一下Handler的相关资料,记录这个笔记。

要点总结

  1. 每个线程中只有一个Looper对象,而Looper对象含有一个MessageQueue对象,每个线程可以含有多个handler对象;
  2. App初始化时,会执行ActivityThread的main方法,在main方法中调用
Looper.prepareMainLooper();
Looper.loop();

进行主线程的Looper初始化;而子线程的Looper初始化需要手动写Looper.prepare()实现(似乎 Android 5.0之后不用手动调用。

  1. Looper的初始化方法中,绑定了当前线程和新建一个MessageQueue对象;

  2. Looper初始化后,需要调用Looper.loop()方法让其运行起来。在主线程中,这个方法会被系统自动调用;子线程中需要自己进行调用。(似乎 Android 5.0之后不用手动调用);

  3. 多个Message通过其自身的.next属性形成一个队列(类似与C语言的链表),而MessageQueue对象对此队列进行管理。

  4. 每个Handler的handleMessage()方法都是执行在初始化该对象的线程中,而其它方法执行在任意线程;

  5. 使用Handler发送消息,最终都会调用带有系统时间的参数的方法,而消息队列中,消息的排序就是根据系统时间进行排序;

  6. Handler的post()方法、View的post方法和Activity的runOnUiThread()方法,都是调用了Handler的发送消息方法。

    Activity的:

    @Override
    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }
    

    View的:

    public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
    
        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }
    

    Handler的:

    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
    
  7. Handler的使用容易引起内存泄漏,一般Android Studio会提示你进行弱引用。

参考文章

  1. 郭霖 Android异步消息处理机制完全解析,带你从源码的角度彻底理解
  2. 工匠若水 Android异步消息处理机制详解及源码分析
上一篇 下一篇

猜你喜欢

热点阅读