Handler消息处理机制--原理分析

本文深入解析了Android中的Handler机制,包括其工作原理、消息传递过程及如何在主线程和子线程中正确使用。

Handler作用:将任务逻辑切换到Handler所在的线程中

使用方式:

核心思想,在一个线程发送消息,在另一个线程接受消息并处理。

发送消息的线程一般不能进行一些耗时的作业,所以交由另一个线程(处理消息的进程)进行处理。

Handler:和looper进行交流, sendmessage时发送消息时将消息存到messagequque中了 按照时间状态。处理looper从messagequeueu取出的事件分发给handler采用callback方式runnble的Run处理了,或者采用handler的handlerMessage方法处理。

Looper:循环消息队列,构造方法中构造了一个messagequeue.(是个共享容器可存可取)内涵循环不断取出消息

messagequeue:采用先进先出的方式存储message

message: 通过设定 obj, what ,等字段存储并运输消息,messege 本质是个单链表,用完回收。(属性值清空)

注意主线程 即UI线程中 系统已经初始化了一个Looper. 所以我们在主线程中处理消息(主线程中一般处理UI更新方面的消息)直接创建Handler对象并覆写Handler处理消息的方法即可。

而 子线程即自己创建的线程,如果作为处理消息的进程,则我们需要进行以下处理:

1调用Looper的prepare()方法为当前进程创建Looper对象()创建对象的同时构造器方法会 自动创建MessageQueue。

2创建Handler对象,并覆写Handler处理方法。用来处理其他线程发送的消息。

3调用Looper的loop方法启动looper.

细节心得:其中massge对象常与bundler连用 进行数据的发送,匹配消息时用msg.what 标记进行匹配。将子线程定义在内部类中方便查找子线程的handler.

Message ms= mhandler.obtainMessage();
                            ms.what = SEND_ROCK;
 ms.sendToTarget();
//这种Masage方式减少内存开销。

子线程中Handle创建r:

  class MyThread extends Thread{

        Handler threadHandler;
        @Override
        public void run() {
            Looper.prepare();
            threadHandler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what){
                        case 0x11:
                            threadHandler.removeMessages(threadSendMsg);
                            synchronized (pagerThread){
                                try {
                                    pagerThread.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                        case 0x12:
                            if (flag){
                                threadHandler.sendEmptyMessageDelayed(threadSendMsg,5000);
                                handler.sendEmptyMessage(changePage);
                    }
                            break;
                        case 0x13:
                                threadHandler.sendEmptyMessageDelayed(threadSendMsg,5000);
                            break;
                    }
                }
            };

            threadHandler.sendEmptyMessageDelayed(threadSendMsg,5000);
            Looper.loop();
        }
    }
并不断发送消息给自己 ,达到定时给主线程的Handler发送消息的逻辑。


注意:导包是 os.handler包!!

工作原理:

创建流程:

Handler创建后 根据当前线程 ThreadLocal(是一个线程内部的数据存储类)会找到一个所在线程的Looper,这个Looper会创建一个MessageQueue。

MessageQueue和Looper 协同工作:

MessageQueue : 是一种单链表数据结构,内部有两个方法 :
                                                                                                        enqueMessage     (这个方法就是链表的插入)
                                                                                                        next   (这个方法是链表的消息循环取出并在链表中删除,没有新消息就阻塞)
Looper 的作用就是不断的查看MessageQueue 中的消息如果有就处理,如果没有就一直阻塞,等待。
Looper会调用Loop方法。Loop方法会调用MessageQueue 的next方法返回不为null就一直等待。

Looper阻塞对子线程的影响和处理:

另外Looper 还有提供两个方法,quit 退出(直接退出)和quitSafely (处理完消息在退出)。如果退出后将收不到任何消息。假设Looper 是在子线程创建的那么当所有事件调用完成后,应该终止Looper 否则它一直阻塞,导致线程也不会停止。
Looper还有一个getMainLooper方法 可以在任意地方获取到主线程的Looper
Looper的停止方法 :
Looper的Loop方法。是一个死循环,会调用MessageQueue 的next方法。唯一跳出的方法是当MessageQueue 的next方法返回Null。而 只有Looper 的quit方法被调用时next方法才会返回NULL。
所以:
要在子线程的Looper 要quilt处理。

Handler post和send 消息的本质:

本质上就是向MessageQueue链表中插入了一条消息。而Looper将消息取出后就开始处理

Looper对消息的处理:

当Looper 获取到message之后  还是交给Handler 处理,Handler 调用dispathcMessage方法。 这个方法是在创建Handler时所使用的Looper执行的。所以又回到,指定的线程中

Handler处理消息的过程:

callback 就是runnable接口。
1.检查callback是否为null,不为null 就调用handlerCallback 方法:其实就是执行runnable 里的run方法。
2.检查mCallback是否为null,不为空就调用mCallback的handleMessage方法。:就是正常的handleMessage方法。

停止handler 和handler 两个构造方法:
 Thread  mmTread=new Thread(new Runnable() {
        @Override
        public void run() {
             Looper.prepare();
             Handler.Callback callback;
             callback=new Handler.Callback() {
                @Override
                public boolean handleMessage(Message msg) {
                    return false;
                }
            };
            Handler handler =new Handler(callback);
            //第二个构造方法绑定一个Looper
            //Handler handler=new Handler(Looper.myLooper());
            Looper.loop();
            //获取当前线程的Looper对像,并退出让这个线程停下来。
            Looper.myLooper().quit(); 
        
        }
    });

通过绑定callback 就不会派生Handler子类。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值