Coin163

首页 > Android中的消息机制-源码分析

Android中的消息机制-源码分析

相关标签: android

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

相关推荐:通过源码分析Android 的消息处理机制

      通过源码分析Android 的消息处理机制 我们知道,Android应用是通过消息来驱动的,每一个进程被fork之后,都会在该进程的UI线程(主线程)中启动一个消息队列,主线程会开启一个死循环来轮训这个队列,处理里面的消息。 通过Android进程的入口 ActivityT

这个话题相信大家都不陌生,本人权当是一次比较系统的梳理。
Handler的几种消息发送方式
在Android中最常用的消息通信机制,即子线程和UI线程之间的通信,我们一般是基于Handler机制实现的,那么下面来看一看Handler的几种发送消息的方式。
1.sendMessage(Message message)
最常用的一种方式,下面我们一层层走下去。最后走到了sendMessageAtTime这个方法。我们见到了MessageQueue,相信大家也都知道,这就是传说中的那个消息队列,那么这个队列到底在哪初始化的呢?
假如我们使用的是new Handler()这个构造函数, 那么最终是调用Handler(Callback callback, boolean async)这个构造函数,可以看到这么行代码 mQueue = mLooper.mQueue,瞬间明朗,原来是Looper中的。(可参见Looper)
2.post(Runnable)
当我们在子线程中执行完之后,然后只想在执行一段代码块,二不需进行一些判断等操作时,我们可以使用该方法。sendMessageDelayed(getPostMessage(r), 0); 按照我们传统的理解,Handler发送消息,Looper取消息,那么现在这里居然没有消息,很奇怪哈。

private static Message getPostMessage(Runnable r, Object token) {
        Message m = Message.obtain();
        m.obj = token;
        m.callback = r;
        return m;
    }

你自己虽然没有取消息,但是系统已经帮你做了,并且还将你的Runnable放到了消息中
后面的流程就和普通的发送消息类似了,走到了enqueueMessage这步。
他有一行重要的代码msg.target = this;
3.在Handler的构造方法中自带CallBack

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

最后是这样的,mCallback = callback;

相关推荐:Android的消息处理机制源码分析

好久没写博客了,最近看了看关于Handler,Looper和MessageQueue的源码,感觉对他们的了解又多了几分,在这整理一下思路,如果有不对的地方,欢迎指正。 先从Looper说起,以下官方文档: Class used to run a message loop for a thread. Threads by default d

再看Looper
让我们一起来细细的研究一下Looper类中的几个方法。
大家都知道UI线程和我们自己线程的区别,这对待Looper上也是有差别的呢。prepareMainLooper方法说的很清楚了,在UI线程启动的时候,系统会主动为你准备好一个MainLooper,这也是我们为什么只需在子线程中将消息发送就可以了,而无需操心主线程中的Looper,但是,如果是我们往子线程中发送消息呢?那么我们就必须调用prepare方法了,他会执行这么一句代码sThreadLocal.set(new Looper(quitAllowed));(可参见ThreadLocal)

private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

MessageQueue有了。
下面再看看Looper的loop()方法,当我们在子线程中调用完prepare()后,便调用该方法,相当于开启轮询器,重要的方法在这里 msg.target.dispatchMessage(msg);
那么这里msg.target就是刚才发送消息的Handler啊,是时候看看dispatchMessage了

public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

我们会先检查callback这个变量,如果我们是用过post方法处理的,那么就是有这个callback的,其实就是你放进去的Runnable,最后会走到这一步message.callback.run();
然后会检查有没有CallBack,通过方法3处理消息就会有这个CallBack,如果没有,才走handleMessage方法。
ThreadLocal是个什么玩意儿呢
上面的方法源码如下:

 public void set(T value) {
        Thread currentThread = Thread.currentThread();
        Values values = values(currentThread);
        if (values == null) {
            values = initializeValues(currentThread);
        }
        values.put(this, value);
    }

1.拿到当前线程
2.拿到当前线程中的ThreadLocal.Values对象
3.将value放进去,键值即为当前的ThreadLocal
那么,我们可以这样理解,在每一个线程中都维护了一个ThreadLocal.Values对象,他相当于一个
集合,用于保存一些引用,那么当我们调用Looper.prepare()时,实际上是new出了一个Looper,然后保存到了ThreadLocal中的Values中。

原文

这个话题相信大家都不陌生,本人权当是一次比较系统的梳理。 Handler的几种消息发送方式 在Android中最常用的消息通信机制,即子线程和UI线程之间的通信,我们一般是基于Handler机制实现的,那

------分隔线----------------------------