`
stone02111
  • 浏览: 212295 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

深度解析Handler类,以及HandlerThread

 
阅读更多

Handler,HandlerThread下次再写;
1)核心成员变量:
final MessageQueue            mQueue;//消息队列,通过Loooper拿到的;
final Looper                                   mLooper;//消息泵,管理消息队列,通过形参传入,我是主线程的Looper;
inal Callback                                   mCallback;//handle的定义的一个内部接口,也是用来接收消息的;

2)核心成员函数;
public interface Callback {//一个回调接口,Handler带一个成员变量,可以通过构造函数的形参传入;
        public boolean handleMessage(Message msg);
    }

**
     * 子类可以继承此方法,用来处理消息;
     */
    public void handleMessage(Message msg) {
    }


   /**
     * 内部派发消息,
*  就是looper这个消息泵的loop()循环方法中通过封装在meesge的handler调用的;
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) //如果消息包含动作,直接指向runnable的方法;
        {
                //运行msg里面的Runnable;
            handleCallback(msg);
        } 
        else 
        {
//判断自身的mCallback,也就是是否有回调监听;
            if (mCallback != null)
            {
                //注意这里的表示,如果不是返回ture的话,还是会调用子类重载的方法;
                    if (mCallback.handleMessage(msg)) //回调;
                {
                    return;//注意这里的返回;
                }
            }
            handleMessage(msg);//调用子类的方法,也就是我们常用的,通过extends handler继承的得到的处理消息的方法;
        }
    }

构造函数1)无参:
    public Handler() {
   //获取当前线程的messageQuenue管理者looper;
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                    //handler对象须有一个对应的Looper;
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        //获取消息队列;
        mQueue = mLooper.mQueue;//获取消息队列;
        //置null回调;
        mCallback = null;
    }

    /**
     * 构造函数2)带回调监听;
     */
    public Handler(Callback callback) {
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
    }


    /**
     *  构造函数3)用提供的looper管理者替换默认的;
     */
    public Handler(Looper looper) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = null;
    }


    /**
     *  构造函数4)替代looper和接口监听;
     */
    public Handler(Looper looper, Callback callback) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
    }

  /**
     * 获取消息成员方法,还有很多,实际都是通过Message类获取的;
     */
    public final Message obtainMessage(int what)
    {
        return Message.obtain(this, what);
    }

非常重要的一个方法:
    /**
     *通过Handler post一个任务runnable到消息队列;
     */
    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

我们分析一下怎么实现的:
1.通过:sendMessageDelayed(getPostMessage(r), delayMillis);
2.getPostMessage(r)的作用就是发挥一个带runnable的Meesage;
    /**
     * 建造带runnable的Msg;
     */
    private final Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;//看到没有,Message的一个成员方法,后续我们会分析Message的;
        return m;
    }
这里Message携带了一个runnable,有什么用了?回到dispatchMessage方法,处理消息的第一步就是处理的msg的run方法;
这样就到达了post一个任务进去的目的;
    /**
     * 运行message.callbakc也就是Runnable的run()方法;
     */
    private final void handleCallback(Message message) {
        message.callback.run();
    }


Handler的消息发送,非常核心的方法,就是通过 MessageQueue 的成员方法把msg插入队列;
    /**
     * 核心方法,基本所有的消息发送都是通过这个方法;
     * 发送一个指定时间的消息;
     */
    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            //抛出运行时异常;
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

辅助方法,主要是清除掉msg消息和callback.因为有个时候退出的时候,或是取消的时候,需要清除前面的方法;
    /**
     * 清楚消息队列中所有what标识的消息;
     */
    public final void removeMessages(int what) {
        mQueue.removeMessages(this, what, null, true);
    }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics