浅浅的介绍一下android里面Handler、Looper、Message和MessageQueue是怎么联系到一起的.

背景介绍:看了网上很多关于android里面消息处理机制的源码解析,觉得很多东西暂时不是我所需要的,为了让更我和我有相同诉求的,只是想粗浅了解一下原理的同胞们更快的获得自己多需要的,而写下这篇博客,小弟第一次写博客,一是有可能自己的理解哪里有疏漏,二是自己表述可能有什么不准确的地方,还请各位前辈指正,我会添加修改,以免误了别人,谢谢。

  1. 先给大家看梳理一下我们要用到的一些类
    Message 这就是你调用Handler对象时发送的消息
    Handler Handler不用介绍了吧,用于发送Message(sendMessage(T))和处理Message(handleMessage(T))所对应事件
    MessageQueue 这个呢就是一个队列,Message队列(有些叨叨的哦这里面)
    Looper 用于不停地查找消息循环,并处理消息

  2. 按照我的心里路程来给大家分享一下,其实我这篇文章只是浅浅的给大家讲讲原理,抛砖引玉,看了它我觉得你会更好的理解网上的源代码分析,且看我娓娓道来
    (1)、给你们看一下Looper的使用

    `class Test extends Activity{
            public void onCreate(){
                ....//为了代码的简介“...”代表不重要代码
    
                //该线程name:线程一
            new Thread{
                public void run(){
                         Looper.prepare();
                         ...//代码段1
                         Looper.loop();//一般要放在run方法最后
                     }
                }.start();
    
            }
    }`
    

    现在呢你就可以在代码段1里面通过定义一个Handler来发送消息给线程一了,然后呢,该消息会添加到一个MessageQueue对象(name:消息队列)中去,然后Looper会通过Looper()方法检测到消息队列中的消息,之后会通过该消息拿到所对应的Handler并执行Handler的dispatchMessage()方法。我一会呢会给大家画一个

“`
// 然后呢,现在我们把 面的语言用代码实现一下:
public class Test extends Activity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {

btn = (Button)findViewById(R.id.btn);
new Thread(){
@Override
public void run() {
Looper.prepare();

            //代码段一
            Handler mHandler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    if (msg.what == 1) {
                        System.out.print("hi");
                        Log.i("hi", "hi");

                    }
                }
            };
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mHandler.sendEmptyMessage(1);

                }
            });
            mHandler.sendEmptyMessage(1);
            mHandler.sendEmptyMessage(1);
            Looper.loop();
        }
    }.start();

}

}
我没有专门的为这段代码测试,原谅我的不严谨,算了等我先去测试下,测试完成可以
其实呢,一开始使我迷茫的是:这几个东西究竟怎么绑定在一起的,我并没有显式的去操作他们四个怎么就可以协调的这么好;还有一个Looper对应几个Messagequeue,又对应几个Handler。其实,看了下面的解说你就知道了。
(2)、代码分析(我只说一下实现之后的结果,具体实现过程可以自行百度)
首先呢,Looper.prepare()这个方法呢,就是在他所处的那个线程中开辟了一片区域,定义了一个仅仅属于这个线程的Looper对象looper(意思就是说,只要某一个线程执行了这句代码,那么这个线程就会对应一个独一无二的Looper对象),
在Looper被创建的过程中会创建一个Messagequeue 对象msgQueue,现在呢,对象looper和msgQueue绑定在了一起;
咱们看下面又new了一个Handler对象mHandler,在你创建mHandler的过程中,假如你不传入参数looper那便会主动获取mHandler所处的线程所绑定的那个本地Looper对象,在这里就是looper,于是Handler和Looper又绑定在了一起;
于是呢,在mHandler里面可以找到looper,在looper里面可以找到msgQueue,然后呢就可以通过mHandler来send消息了,添加到消息列表msgQueue里面。再向后面走,Looper.poor()方法就开始起作用了,这个方法就是一个for(;;)不停地循环着来检查消息列表,拿到一条通过mHandler.send()过来的消息,然后呢,怎么跳转到mHandler的handleMessage方法去执行呢,怎么能从send过来的消息找到所对应的mHandler呢(之所以说所对应的的,请向下看),其实在每一个Message里面,都有一个参数叫target,那这个参数是干嘛的呢,这个参数就是用来引用mHandler的,怎么应用到mHandler呢,你看啊
在调用mHandler.send(msg)时,会执行一句代码msg.target = this;这个this自然就是mHandler。
于是呢,现在再来梳理一下,给你们上张图

这里写图片描述

    不知怎么的,图片上传不上来,一会再在下辺尝试吧,总之,这几个东西相互转了个圈,都可以找到对方。

这里面我并有给大家讲什么源码,仅仅是从原理上就自己之前不明白的地方介绍了一下而已,大家可以百度一下ThreadLocal,看看java是怎么为某个线程提供独立副本的,还有建议大家还是去读读源码,相信读了我的这篇在读其他人写的也会更好理解一点,为了尽量简化我要叙述的内容,也就是这几个东西究竟怎么联系起来的,所以消息传递机制里面有很多其他内容我并没有做出提示之类了,所以建议大家再看看别人写的,还有我也还是小白一枚,有什么写的不对的地方也请大家指正。谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值