Handler消息机制完全解析Handler解析

作者: goodgleCoder | 来源:发表于2017-07-16 14:46 被阅读22次

    Handler

    Handler总是依附于创建时所在的线程,比如我们的Handler是在主线程中创建的,而在子线程中又无法直接对UI进行操作,于是我们就通过一系列的发送消息、入队、出队等环节,最后调用到了Handler的handleMessage()方法中,这时的handleMessage()方法已经是在主线程中运行的,因而我们当然可以在这里进行UI操作了。整个异步消息处理流程的示意图如下图所示:

    异步消息处理流程

    Handler

    这便是我们平时直接使用的主角。继承Handler
    重写其handleMessage()
    方法来处理消息,在需要的时候调用sendMessage()
    来发消息,剩下的就不用管了。现在来看看“我们不用管”的这部分都干了点啥。

    构造方法

    所有的构造方法最终会会调用两个实现,如果制定了Looper,则会调用三个参数的重载,否则会调用两个参数的重载。而后者则会调用Lopper.myLooper()
    来获取looper。两个构造方法除了给mLooper
    赋值外,还给mQueue
    赋值为mLooper.mQueue
    ;给mCallback
    赋值为指定的callback或null;给mAsynchronous
    赋值为指定的boolean或false。 在两个参数的构造方法中,给上述四个成员赋值前有段if(FIND_POTENTIAL_LEAKS){}
    包裹的代码段,该变量定义为private static final boolean FIND_POTENTIAL_LEAKS = false;
    因此推断这部分是开发时调试用的,此处不做理会。

    创建消息obtainMessage()

    根据源码可以看出,所有该方法的重载都调用了Message.obtain()
    对应的重载,可以看Message.obtain()的来龙去脉来了解,此处不再赘述。需要注意的是,每个重载都传入了this
    参数并赋值给了message的target
    。这里先记着就行,后面会介绍如何通过target
    调用dispatchMessage()
    处理消息。

    发送消息sendMessage()

    所有的sendEmptyMessage()
    重载与sendMessageXXX()
    以及postXXX()
    最终都会调用enqueueMessage()
    方法,该方法则调用queue.enqueueMessage()
    方法将消息添加到消息队列。关于消息队列如何管理消息可以看MessageQueue的队列管理一文。

    移除消息removeMessage()

    所有的removeMessages()
    重载与removeCallbacks()
    重载最终都是调用mQueue.removeMessages()
    方法,即通过MessageQueue来实现该操作。详细分析可以看MessageQueue的队列管理一文。

    处理消息dispatchMessage()

    消息处理最开始被调用的不是handleXXX()
    方法,而是dispatchMessage()
    方法。该方法会根据消息是否有callback
    来判断该交给handleCallback()
    还是handleMessage()
    。前者直接调用参数中message
    的message.calback.run()
    解决问题,后者则是空方法体,需要我们开发者自己重写。

    Handler一些特点

    • handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),它有两个作用:

      • (1)安排消息或Runnable 在某个主线程中某个地方执行;

      • (2)安排一个动作在不同的线程中执行。

    Handler实例

    • 子类需要继承Hendler类,并重写handleMessage(Message msg) 方法, 用于接受线程数据。

    • 以下为一个实例,它实现的功能为:通过线程修改界面Button的内容

    public class MyHandlerActivity extends Activity { 
        Button button; 
        MyHandler myHandler; 
     
        protected void onCreate(Bundle savedInstanceState) { 
            super。onCreate(savedInstanceState); 
            setContentView(R。layout。handlertest); 
     
            button = (Button) findViewById(R。id。button); 
            myHandler = new MyHandler(); 
            // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据 
            // Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象 
            // (2): 让一个动作,在不同的线程中执行。 
     
            // 它安排消息,用以下方法 
            // post(Runnable) 
            // postAtTime(Runnable,long) 
            // postDelayed(Runnable,long) 
            // sendEmptyMessage(int) 
            // sendMessage(Message); 
            // sendMessageAtTime(Message,long) 
            // sendMessageDelayed(Message,long) 
          
            // 以上方法以 post开头的允许你处理Runnable对象 
            //sendMessage()允许你处理Message对象(Message里可以包含数据,) 
     
            MyThread m = new MyThread(); 
            new Thread(m)。start(); 
        } 
     
        /** 
        * 接受消息,处理消息 ,此Handler会与当前主线程一块运行 
        * */ 
     
        class MyHandler extends Handler { 
            public MyHandler() { 
            } 
     
            public MyHandler(Looper L) { 
                super(L); 
            } 
     
            // 子类必须重写此方法,接受数据 
            @Override 
            public void handleMessage(Message msg) { 
                // TODO Auto-generated method stub 
                Log。d("MyHandler", "handleMessage。。。。。。"); 
                super。handleMessage(msg); 
                // 此处可以更新UI 
                Bundle b = msg。getData(); 
                String color = b。getString("color"); 
                MyHandlerActivity。this。button。append(color); 
     
            } 
        } 
     
        class MyThread implements Runnable { 
            public void run() { 
     
                try { 
                    Thread。sleep(10000); 
                } catch (InterruptedException e) { 
                    // TODO Auto-generated catch block 
                    e。printStackTrace(); 
                } 
     
                Log。d("thread。。。。。。。", "mThread。。。。。。。。"); 
                Message msg = new Message(); 
                Bundle b = new Bundle();// 存放数据 
                b。putString("color", "我的"); 
                msg。setData(b); 
     
                MyHandlerActivity。this。myHandler。sendMessage(msg); // 向Handler发送消息,更新UI 
     
            } 
        } 
    }
    

    如果你觉
    得此文对您有所帮助,欢迎入群 QQ交流群 :232203809
    微信公众号:终端研发部

    技术+职场

    相关文章

      网友评论

        本文标题:Handler消息机制完全解析Handler解析

        本文链接:https://www.haomeiwen.com/subject/yjutkxtx.html