深入Android Handler源码,分析主线程、子线程通讯原理
2017-01-12 16:54
483 查看
Android工作已经用不少的时间了,后悔当初没有写博客。最近一段时间才开始写博客的,其实我感觉并不是技术很厉害的人,才可以写博客。我写博客的原因,主要就是督促自己学习,不断的提升的自己。
好吧!废话不多说,开始今天的主题吧!Handler,大家可能看到Handler之后都感觉,这个我会用,不就Android里面经常用来更新UI的么,对,这么说也不是不对。但是这么说的肯定是没有对Handler或者AsyncTask有过深入研究的,首先Handler并不是用来更新UI的,它的作用是子线程与主线程通讯,更新UI只是随便。
好的下面我们开始先分析下Handler的源码!我们在使用Handler的时候主要是使用的sendMessage方法,那么我们进到sendMessage方法里面看看,它是这样的↓一般走到这一步之后就看不到源码了。(因为API版本不同,可能看到也不同所以没有关系,明白流程就好)
最后会进入到这样一个方法里面↓(高版本的API已经进行了进一步的封装,这是在低版本找到的)
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
看到这里大家可能就会看明白许多了,这个方法就是把消息压入到了消息队列当中了,等待Looper进行抽取处理。那它是怎么拿到消息的呢?刚才就说了是Looper进行轮询抽取,那么到Looper类中可以看到一个loop方法,看重点,它是调用了消息队列的.next方法,将消息在队列中抽取出来,也就是说enqueue入队,next出队。
那么我就该说说Looper了,它是怎么用的。想用Looper必须要调用它的prepare()方法,那么这个方法是干什么的呢?看代码!
通过代码一看就看出来最后new
了一个Looper。对他就是用来实例化Looper对象的,但是你可能会看到一个叫sThreadLocal的变量,那么它是用来干什么的呢?我就直接跟大家说了吧!它是在java的并发包中的,主要是用来数据隔离的,比如线程中需要一个变量,但是线程的数量又不确定,也就是说每个线程中的这个变量都不一定是什么,但是又怎么能准确的拿到呢?就用到了这个ThreadLocal,它的主要功能就是防止数据脏读,用来进行数据隔离的。调用set就是将数据放进去。Loope又通过myLooper将Looper对象取出。也就是说,那一个线程调用prepareI()方法,这个线程就会关联一个Looper对象,那这个Looper.prepare是什么时候调用呢?为什么我们用Handler的时候为什么没有调用呢?
大家到Activity中可以去看看,在main方法中,系统就已经帮我们调用了,(在main方法中调用了Looper.prepareMainLooper),所以我们可以直接使用Handler。
大家是不是感觉这篇博客全是文字很无聊啊?其实我也感觉到了!我已经是捞干的了,大家见谅啊!
那么我们总结下:Hanlder的机制是不是这样的?子线程调用sendMessage方法将消息压入消息队列之后,主线程开了一个Looper轮询器,不断的轮询从这个Handler发送过来的消息,轮询到了之后调用handlerMessage方法进行处理。过多的细节我就不给大家阐述了,在下献上一副图供大家参考↓
好了,多了我就不说了!我用java代码简单的实现了一下Hanlder,有兴趣的朋友们可以下载下来看看,有不同意见的可以留言吐槽。
a1b7
好吧!废话不多说,开始今天的主题吧!Handler,大家可能看到Handler之后都感觉,这个我会用,不就Android里面经常用来更新UI的么,对,这么说也不是不对。但是这么说的肯定是没有对Handler或者AsyncTask有过深入研究的,首先Handler并不是用来更新UI的,它的作用是子线程与主线程通讯,更新UI只是随便。
好的下面我们开始先分析下Handler的源码!我们在使用Handler的时候主要是使用的sendMessage方法,那么我们进到sendMessage方法里面看看,它是这样的↓一般走到这一步之后就看不到源码了。(因为API版本不同,可能看到也不同所以没有关系,明白流程就好)
最后会进入到这样一个方法里面↓(高版本的API已经进行了进一步的封装,这是在低版本找到的)
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
看到这里大家可能就会看明白许多了,这个方法就是把消息压入到了消息队列当中了,等待Looper进行抽取处理。那它是怎么拿到消息的呢?刚才就说了是Looper进行轮询抽取,那么到Looper类中可以看到一个loop方法,看重点,它是调用了消息队列的.next方法,将消息在队列中抽取出来,也就是说enqueue入队,next出队。
那么我就该说说Looper了,它是怎么用的。想用Looper必须要调用它的prepare()方法,那么这个方法是干什么的呢?看代码!
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
通过代码一看就看出来最后new
了一个Looper。对他就是用来实例化Looper对象的,但是你可能会看到一个叫sThreadLocal的变量,那么它是用来干什么的呢?我就直接跟大家说了吧!它是在java的并发包中的,主要是用来数据隔离的,比如线程中需要一个变量,但是线程的数量又不确定,也就是说每个线程中的这个变量都不一定是什么,但是又怎么能准确的拿到呢?就用到了这个ThreadLocal,它的主要功能就是防止数据脏读,用来进行数据隔离的。调用set就是将数据放进去。Loope又通过myLooper将Looper对象取出。也就是说,那一个线程调用prepareI()方法,这个线程就会关联一个Looper对象,那这个Looper.prepare是什么时候调用呢?为什么我们用Handler的时候为什么没有调用呢?
大家到Activity中可以去看看,在main方法中,系统就已经帮我们调用了,(在main方法中调用了Looper.prepareMainLooper),所以我们可以直接使用Handler。
大家是不是感觉这篇博客全是文字很无聊啊?其实我也感觉到了!我已经是捞干的了,大家见谅啊!
那么我们总结下:Hanlder的机制是不是这样的?子线程调用sendMessage方法将消息压入消息队列之后,主线程开了一个Looper轮询器,不断的轮询从这个Handler发送过来的消息,轮询到了之后调用handlerMessage方法进行处理。过多的细节我就不给大家阐述了,在下献上一副图供大家参考↓
好了,多了我就不说了!我用java代码简单的实现了一下Hanlder,有兴趣的朋友们可以下载下来看看,有不同意见的可以留言吐槽。
a1b7
相关文章推荐
- Android进程/线程管理——深入源码解读+分析
- Android phoneGap 源码分析之js-android通讯原理
- 【Android 源码解析】从源码角度深入分析Handler消息机制
- Android线程间消息机制-Handler源码分析(FrameWork)
- Android 中线程间通信原理分析:Looper, MessageQueue, Handler
- Android Handler如何实现线程间通信,源码分析。
- Android中Handler的线程间通讯原理
- Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
- Android Handler 机制以及各方法所在线程原理分析
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
- 【图灵学院09】RPC底层通讯原理之Netty线程模型源码分析
- 源码分析Android Handler是如何实现线程间通信的
- Android中Handler的线程间通讯原理
- Android 从源码出发深度理解Handler线程通讯机制(这一篇就够了)
- 【Android源码解析】从源码角度深入分析AsyncTask原理
- android addIdleHandler 空闲线程 源码分析
- Android之Handler源码深入分析
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
- 源码分析Android Handler是如何实现线程间通信的
- Android线程通信:Handler,MessageQueue和Looper原理分析