安卓消息机制

  安卓开发在处理不同线程通信的时候有一套消息处理机制,安卓的主线程(UI线程)是不允许处理耗时任务的。所以一般耗时任务比如常见的网络下载等任务都是子线程完成,子线程完成之后通知主线程更新UI,利用Handler类实现不同线程之间的通信:

    

1:实例化Message msg = mHandler.obtainMessage();

 public final Message obtainMessage()
    {
        return Message.obtain(this);//调用的是Message类中的obtain }

  Handler类中obtainMessage方法实际调用的还是Message的static方法obtain(Handler);

    public static Message obtain(Handler h) { //Message中obtain的源码
        Message m = obtain();//这里是Message获取消息队列中的消息
        m.target = h;//这里会传入想要获取Message的Handler,这样就会实现Message与Handler的绑定
             //在Looper的循环中会调用Handler的dispatchMessage方法,而dispatchMessage
             //调用的还是handleMessage(..);所以在处理异步通信的时候在主线程要重写handlerMessage
             //方法来处理消息,通过what来确认消息标示
return m; }

  这里传入了Handler与消息绑定起来,这这个方法最终调用的是重载的方法obtain();

public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }

   这里其实先在全局的消息池中,获取Message对象,其中sPool = m.next;类似于链表里的指针域(结构类似于)next其实是Message类定义的Message对象;如果消息池中有现成的对象,就只会取出,不用重新new,如果没有就返回一个
新new的消息对象。

2:获取消息对象之后用Handler(处理器)来发送消息

  mHandler.sendMessage(msg);看看源码

  public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0); }

这里实际调用的是sendMessageDelayed(msg,0);这里不是延时发送消息,而是延时处理消息,只不过延时时间设定的是0;

以上获取消息发送消息都是在子线程里处理的。在主线程中用Handler类处理消息

3:Handler类的构造函数需要指定回调接口,Handler类有一个接口Callback中有一个handleMessage方法,在Handler中也有一个同名方法。

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

如果不指定回调接口就要重写方法:handleMessage();

/**
     * Subclasses must implement this to receive messages.
     */
    public void handleMessage(Message msg) { }

注释写得很清楚如果是用Handler的子类来处理消息就必须重写这个类类接受消息。
另外也可以用匿名内部类的方式来重写接口Callback里的handleMessage;

 private Handler myHandler = new Handler(new Handler.Callback(){
        @Override
        public boolean handleMessage(Message msg) { return true; } });

获得消息之后就可以做相应的处理。首先要更具Message的what属性来确定是否是自己需要的消息,这个可以在发送消息的时候指定。
这里要明确Handler是如何处理消息的实际上是调用dispatchMessage();看源码

/**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg);//这里会有限处理Message指定的回调函数 } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }

这个方法首先会判断Message本身是否定义了回调,如果有,那么直接调用handlerCallback(msg);

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

从代码可以看出最终调用的是Message调用的callback,而Message定义的callback字段实际上是Runnable接口,所以要调用run启动线程;
也就是说可以通过消息来启动一个子线程;

如果在实例化Message的时候没有指定回调就会判断mCallback是否实例化,mCallback是Handler定义的一个final CallBack接口字段。这个在

Handler实例化的时候调用对应的构造函数来指定

public Handler(Callback callback) {
        this(callback, false);
    }

如果调用的是无参构造函数的话要么用匿名内部内指定Callback,要么自己定义个Handler的子类重写handleMessage()方法。

dispatchMessage(..)也可以看出:1、如果Message实例化没有指定回调

                2、如果没有重写Handler类的接口CallBack中的 boolean handleMessage()方法

                3、最后才会执行Handler类中的方法void handlerMessage();

转载于:https://www.cnblogs.com/ashitaka/p/5849559.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值