Android:Handler消息机制(三)——Handler源码分析

一、处理者Handler类里的主要方法:

Handler():构造方法

sendMessage(Message msg):将消息发送到消息队列

post(Runnable r):将消息发送到消息队列

dispatchMessage(Message msg):将消息发送给对应的Handler

handleMessage(Message msg):根据某一个消息进行相关的处理和操作

 

(1)Handler构造方法

Hander具备多种构造函数:

public Handler()

public Handler(Callback callback)

public Handler(Looper looper)

public Handler(Looper looper ,CallBack callback)

等等。

public Handler() {
    this(null, false);
}


public Handler(Callback callback, boolean async) {
    ...
    //Looper.myLooper()作用:指定Looper对象,获取当前线程的Looper对象;
    //若线程无Looper对象则抛出异常,也就无法创建Handler对象,需先创建Looper对象,也可以通过Loop.getMainLooper()获得当前进程的主线程的Looper对象
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");
    }
    // 绑定消息队列对象(MessageQueue),获取该Looper对象中保存的消息队列对象(MessageQueue)
    mQueue = mLooper.mQueue;
}

Handler对象需要绑定线程才能使用,绑定方式需要指定Looper对象,因为会通过构造方法自动关联当前线程的Looper对象与对应的消息队列对象(MessageQueue),同时Looper对象本身已经绑定了对应线程,这样当绑定了 Looper对象所绑定的线程,从而就自动绑定了实现创建Handler对象操作的线程,绑定后Handler的消息处理会在绑定的线程中执行。 也就是说指定了Handler对象的 Looper对象 = 绑定到了Looper对象所在的线程。

至此,保证了handler对象关联上Looper对象中MessageQueue。

 

(2)发送消息

public void dispatchMessage(Message msg) {
    //  若msg.callback属性不为空,则代表使用了post(Runnable r)发送消息,则执行handleCallback(msg),回调Runnable对象里复写的run()
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            //在mCallback不为空的情况下调用mCallback.handleMessage(msg)
            //除了通过handlermessage来改变行为,还可以通过重载dispathMessage来解决
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        //若msg.callback属性为空,则代表使用了sendMessage(Message msg)发送消息
        //则执行handleMessage(msg),即回调复写的handleMessage(msg)
        handleMessage(msg);
    }
}

private static void handleCallback(Message message) {
        message.callback.run();
}

作用:属于处理者类(Handler)中的方法,派发消息到对应的Handler实例并根据传入的msg作出对应的操作,出队消息的归属者通过dispatchMessage(msg)进行分发,最终回调复写的handleMessage(Message msg),从而实现消息处理的操作,进行消息分发时会进行1次发送方式的判断:

当msg中有callback时,即msg.callback属性不为空,则调用message.callback.run(),其中的callback指的是Runnable,代表使用了post(Runnable r)发送消息,则直接回调Runnable对象里复写的run()。

若msg.callback属性为空,那么看一下成员变量的mCallback是否为空,这个是Handler的构造方法传入的,不为空则代表使用了sendMessage(Message msg)发送消息,则回调复写的handleMessage(msg),如果mCallback也为空,则调用handleMessage方法,这个一般在Handler的子类中重写。

 

Handler 里藏着的 Callback 能干什么?

Handler.Callback 有优先处理消息的权利 ,当一条消息被 Callback 处理并拦截(返回 true),那么 Handler 的 handleMessage(msg) 方法就不会被调用了;如果 Callback 处理了消息,但是并没有拦截,那么就意味着一个消息可以同时被 Callback 以及 Handler 处理。也就是说可以利用 Callback 这个拦截机制来拦截 Handler 的消息

 

(3)消息处理

public void handleMessage(Message msg) {  
    //是一个空方法
} 
作用:handleMessage(msg)该方法为空方法

public interface Callback {
    public boolean handleMessage(Message msg);
}

作用:在创建Handler实例时复写相当于自定义消息处理方式,Message对象的callback属性为传入的Runnable对象,即回调Runnable对象里复写的run()

 

(4)sendMessage发送消息

public final boolean sendMessage(Message msg){
    return sendMessageDelayed(msg, 0);//调用逻辑
}

public final boolean sendMessageDelayed(Message msg, long delayMillis){
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    //调用逻辑,该方法会调用sendMessageAtTime()方法。
    //其中第二个参数是执行消息的时间,是通过从开机到现在的毫秒数(手机睡眠的时间不包括在内)+ 延迟执行的时间
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

}

public boolean sendMessage
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值