消息处理机制

Message:根据android源码可以知道,在ActivityThread.java中
在main函数中,执行了Looper.prepareMainLooper()和Looper.loop();

主线程会自动创建MessageQueue。

Message,本质上也是一个链表。
Message.obtain()就是从message池中拿缓存的message,若没有才新建一个message

Mesage.obtain(Handler handler)其实就是obtain一个message,把message的target设置成是发给handler处理

Mesage.obtain(handler,runable)其实就是再赋值了一个callback给message。
Message.obtain(handler,what)其实就是再赋值了一个id给message,以鉴别message

Message.obtain(handler,what,obj)就是再赋值了一个object给message
还有(handler,what,arg1,arg2)还有handler,what,handler,arg1,arg2。arg1,arg2都是用来传参数的

recycle()方法就是将message回收到message池中,清空message,使用到了指针,让spool(message池)重新指向本message。
让下一message及next指向spool原来指向的地方


MessageQueue:

Looper:
为什么要prepare(对于UI线程,Looper有专门的prepareMainLooper来准备,这些由系统完成):
每一个现成如果要分发消息必须先Looper.prepare()然后Looper.loop()、
在Looper中有一个ThreadLocal对象,而且是static final。它是用来存储每个线程的Looper的。
Prepare()的工作是:简单说就是初始化线程的trheadLocal值(looper。)为当前线程的threadLocal值设置looper值。通过new一个looper。

loop()的工作是:获取当前现成的 looper分发looper的消息队列mQueue的消息,到不同的handler进行处理。

ThreadLocal其实就是一个为每个Thread存储一个对象(T)值的map。
就是Thread里的localValues。Set()方法的时候根据当前线程来影射。Get的时候根据当前线程来获取。




Handler:
定义了一个借口Callback

构造函数Handler():初始化的时候就自动绑定了handler与当前现成的队列,即handle理的queue和绑定的线程的队列一样了。里面执行了Looper,prepare()。

构造函数Handler(Looper):意思很明显。
Handler(Looper,CallBack)

Obtain(Message),和Message.Obtain()差不多,只是设定了messge的target是handler

DispatchMessage(Message)处理消息:
先:如果message的(Runable)callback不空就执行callback的回调(run())。否则执 行handler的callback的回调(handleMessage())。
然后:handle去处理消息。

Post(Runable)其实就是添加一个message whose callback是runable的



Thread:
volatile 类型修饰符 阻止编译器优化 每一次取值都是重新读取。而不是读取保存在寄存器中的值。因此连续的两次取值,结果可能会不同、



总结:
Looper 一个环形,不断的循环发送消息到targetHandler去处理。由于本身的这种性质,导致它经常和Thread一起使用,因为Thread也是处于一种动态不间断的状态。Looper.prepare()根据java的设计原理,它是给当前所在线程新建一个Looper。Looper.loop()里面有一个无限循环负责将loop里的message一一个办了(意思就是由这个message的目标handler给处理了)。
Handler消息的最终处理者,构造的时候,会自动去获取当前线程的Looper。一个Handler永远只拥有一个Looper。如果这个线程没有Looper(就是在这个线程的开头没有执行Looper.prepare的话)就会抛出那个异常啦。构建成功了,handler负责发送消息,处理消息。SendMessage就是将消息插入到当前Handler的消息队列中MesageQueue。其中又涉及到了send的很多方法,立即插入的啊,过一段时间出入的啊。
Message 本身就是一个链表,比较重要的一个地方就是只要Message有实现callback或者handler里面有实现callback的话,handler去handleMessage处理消息的时候就会先执行message的callback或者先执行handler的callback。
还有一个比较重要的:它里面有一个静态变量sPool也是message它是一个message池,存储着闲置的message,哪种obstain消息的方法都是从这个池子里获取。
MessageQueue 别被表象迷惑了,它就不是链表了,实际上还是message来存储Message。Message是MessageQueue的一个变量嘛。

Looper,英文意思环形,也就是无限循环,这样想就对了。Looper有两个非常重要的方法,Looper.prepare和Looper.loop(),它们是干嘛的呢?首先:
Looper.prepare():瞧了瞧源代码,原来是这样,就执行了sThreadLocal.set(new Looper(quitAllowed));这样一句。这个是干嘛呢,又去瞧了瞧sThreadLocal是什么东西,搞来搞去大概就是这个意思:一个线程对应一个Looper,类似于通过键值对的方式保存在一个不为人知的地方(自己去看啦,不但可以存Looper,还可以存好多好多东西呢),所以通过looper可以获知宿主线程,通过线程也可以知道对应的Looper,而上面那条语句就是做了这样的一个事情,让他们两个之间建立非常亲密的一一对应的关系。简单的说prepare()的作用就是new了一个looper,然后把它嫁给了当前所在的线程,永远不分开了。
Looper.loop():这个方法和上面那个方式是一起用的,也是非常的亲密。它是干嘛的呢,瞧了瞧源代码,一堆代码原来就做了这样一件狗屁简单的事,loop自己有一个messageQueue变量,这个变量的意思就是消息队列,所以它装的尽是些Message,loop()就无限循环不要命的去翻这个messageQueue里面的Message,已经发现Message,就把它给办了,怎么办了,这样一条语句给办了 msg.target.dispatchMessage(msg);它这是干嘛啊,它的意思就是叫message的老婆handler(target)把它给办了,在dispatch里面呢,先会执行msg或者handler的回调借口callback,不空的话就执行这个就可以了,不去执行handleMessage()。如果为空的话,就是我们平常用的情况,执行handler的handleMessage把这个msg给办了。简单的说,loop就是启动循环,处理这个线程的looper的消息队列里的消息。
Handler ,表面意思就是处理者,它就是消息的最终处理者。扒了handler的衣服,嘿嘿看看好不好看啊?一看吓一跳,也不过如此。
handler构造的时候,神不知鬼不觉地就去获取当前线程的looper,原来handler也是它的唯一(一一对应)。会出现 “Can’t create handler inside thread that has not called Looper.prepare()”);这个异常的原因,就是因为handler找不到它亲爱的looper了,要知道,一个线程被创建,必须手动looper.prepare()去创建这个线程的looper。那你会说activity里面创建怎么就不会了,很明显啦,activity对应的是一个特殊线程ActivityThread,系统已经执行了looper.prepareMainLooper了还有Looper.loop()了。明白这个异常的原因了吧,所以在一个自建的线程Thread里,如果有new Handler()这样的语句,必须在前面增加Looper.prepare()来给这个thread生成一个looper,当然在最后也别忘了执行Looper.loop()。

Handler.sendMessage不要以为他把消息发给别个谁了,其实他就是把消息Message插到自己的messageQueue里了,所以记着了,sendMessage就是插入消息到队列中。还有很多“乱七八糟”的发送方法,无法就是啥时候插入到消息队列当中去嘛。
Handler.handleMessage 空方法,必须要自己实现。
Handler.dispatchMessage:asdf 分发消息,我是觉得没必要理解成是分发消息的意思,就是处理消息的意思。和上面什么区别,这个处理时先看看message或者handler的callback回调接口是否空的,不空就执行。前面i两个加上handleMessage,只会执行其中一个,先后次序就是这里的文字先后顺序。
Message:本身就是一个链表,比较重要的地方就是只要Message有实现callback或者handler里面有实现callback的话,handler去handleMessage处理消息的时候就会先执行message的callback或者先执行handler的callback。
还有一个比较重要的:它里面有一个静态变量sPool也是message它是一个message池,存储着闲置的message,obstain消息的方法都是从这个池子里获取。

点击事件分发机制

Android事件分发流程
注意:一系列的事件处理,只有return true了才能不断的处理后续的action,如果返回false,则中断处理。
1.View的事件分发
简单的说:
事件是从View中的dispatchTouchEvent中分发下去,这个方法的实现适用于所有的视图组件(Button,TextView,ImageView,等等),但是在ViewGroup中重写了dispatchTouchEvent方法。
1.首先触发view所在的父布局的dispatchTouchEvent()方法。
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
return true;
}
if (onTouchEvent(event)) {
return true;
}
}
如果view本身注册的touchListener不为空,则先执行这个listener的onTouch方法,如果返回为true,则直接返回,不执行onTouchEvent(MotionEvent)方法。
2.否则,继续执行onTouchEvent()方法。在case ActionUP中执行了performClick(onclickListener监听)。在case Action_DOWN中执行了checkForLongPressed()。
在onTouchEvent中:
if (((viewFlags & _CLICKABLE
) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
只要上句话成立,即可点击的话,就会返回onTouchEvent()就会返回true。
注意:在action_down的时候返回false将导致后续action不会得到执行。简单的说只有前一个action返回了true才会触发后一个action
ViewGroup事件分发
viewGroup必须复写dispatchTouchEvent,因为它不同于其他组件,它是一个view的容器,因此它有许多子布局,必须考虑到事件分发给子控件的问题。
DispatchEvent
1.dispatchTouchEvent方法开始需要判断intercepted的boolean值。这个值的意思是是否拦截事件。如果为true,即拦截事件,则不会考虑将事件分发给子布局。 intercepted = onInterceptTouchEvent(ev);
2.如果为false,且没有被cancel掉。则会考虑将事件派发给子布局,遍历子控件,通过坐标区域来确定应该派发给哪个子布局。
圣达菲
dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)

  1. 在上方法中 intercepted = onInterceptTouchEvent(ev);
  2. 4��intercepted��ֵ��

综上:



是View时:dispatchTouchEvent() onTouch(为true则直接返回) onTouchEvent(为true则返回true,为false则返回false,里面执行了click方法)



是ViewGroup时,ViewGroup.dispatchTouchEvent 在上述方法中intercepted = onInterceptTouchEvent() 为true,则执行子布局的dispatchTouchEvent


View。dispatchTouchEvent()。为false的话,子布局不能获得事件,TagertChild为null,在dispatchTransformedTouchEvent中,因为child等于null,执行super。dispatchTouchEvent。

cellon消息处理机制

demo.txt
Handler.java
Looper.java
Message.java
MessageQueue.java

Handler介绍.ppt

Message :根据 android 源码可以知道,在 ActivityThread.java中
在 main函数中,执行了 Looper.prepareMainLooper() 和Looper.loop() ;

主线程会自动创建 MessageQueue 。

Message ,本质上也是一个链表。
Message.obtain() 就是从 message池中拿缓存的 message ,若没有才新建一个 message

Mesage.obtain(Handler handler) 其实就是 obtain 一个message ,把 message的 target 设置成是发给 handler处理

Mesage.obtain ( handler, runable )其实就是再赋值了一个 callback 给message 。
Message.obtain(handler,what) 其实就是再赋值了一个 id 给message ,以鉴别 message

Message.obtain ( handler, what ,obj )就是再赋值了一个 object 给message
还有( handler ,what , arg1, arg2 )还有handler , what, handler ,arg1 , arg2。 arg1 ,arg2 都是用来传参数的

recycle ()方法就是将 message回收到 message 池中,清空 message,使用到了指针,让 spool (message 池)重新指向本 message 。
让下一 message 及next 指向 spool原来指向的地方

MessageQueue :

Looper :
为什么要prepare ( 对于UI 线程, Looper有专门的 prepareMainLooper 来准备,这些由系统完成 ):
每一个现成如果要分发消息 必须先 Looper.prepare()然后 Looper.loop() 、
在Looper 中有一个 ThreadLocal 对象,而且是 static final。它是用来存储每个线程的 Looper 的。
Prepare()的工作是 :简单说就是初始化线程的 trheadLocal 值(looper 。)为当前线程的 threadLocal 值设置looper 值。通过 new 一个looper 。

loop()的工作是: 获取当前现成的 looper 分发looper 的消息队列 mQueue 的消息,到不同的 handler进行处理。

ThreadLocal其实就是一个为每个 Thread 存储一个对象( T)值的 map 。
就是Thread 里的 localValues。 Set ()方法的时候根据当前线程来影射。 Get 的时候根据当前线程来获取。

Handler :
定义了一个借口 Callback

构造函数 Handler ():初始化的时候就 自动绑定了 handler 与当前现成的队列,即 handle理的 queue 和绑定的线程的队列一样了。里面执行了 Looper,prepare ()。

构造函数 Handler (Looper ) :意思很明显。
Handler (Looper , CallBack)

Obtain (Message ), 和Message.Obtain ()差不多,只是设定了 messge 的target 是 handler

DispatchMessage ( Message)处理消息:
先:如果message 的( Runable) callback 不空就执行 callback的回调( run ())。否则执 行 handler 的callback 的回调( handleMessage ())。
然后:handle 去处理消息。

Post( Runable )其实就是添加一个 message whose callback 是runable 的

Thread :
volatile 类型修饰符 阻止编译器优化 每一次取值都是重新读取。而不是读取保存在寄存器中的值。因此连续的两次取值,结果可能会不同、

总结:
Looper 一个环形,不断的循环发送消息到 targetHandler 去处理。由于本身的这种性质,导致它经常和 Thread 一起使用,因为 Thread也是处于一种动态不间断的状态。 Looper.prepare() 根据java 的设计原理,它是给当前所在线程新建一个 Looper 。Looper.loop() 里面有一个无限循环负责将 loop 里的message 一一个办了(意思就是由这个 message 的目标handler 给处理了)。
Handler 消息的最终处理者,构造的时候,会自动去获取当前线程的 Looper 。一个Handler 永远只拥有一个 Looper 。如果这个线程没有 Looper(就是在这个线程的开头没有执行 Looper.prepare 的话)就会抛出那个异常啦。构建成功了, handler 负责发送消息,处理消息。 SendMessage 就是将消息插入到当前 Handler的消息队列中 MesageQueue 。其中又涉及到了 send的很多方法,立即插入的啊,过一段时间出入的啊。
Message 本身就是一个链表,比较重要的一个地方就是只要 Message 有实现callback 或者 handler里面有实现 callback 的话,handler 去 handleMessage处理消息的时候就会先执行 message 的callback 或者先执行 handler 的callback 。
还有一个比较重要的:它里面有一个静态变量 sPool 也是message 它是一个 message 池,存储着闲置的 message,哪种 obstain 消息的方法都是从这个池子里获取。
MessageQueue 别被表象迷惑了,它就不是链表了,实际上还是 message 来存储Message 。 Message是 MessageQueue 的一个变量嘛。

Looper ,英文意思环形,也就是无限循环,这样想就对了。 Looper 有两个非常重要的方法, Looper.prepare 和Looper.loop() ,它们是干嘛的呢?首先:
Looper.prepare() :瞧了瞧源代码,原来是这样,就执行了 sThreadLocal.set(new Looper(quitAllowed));这样一句。这个是干嘛呢,又去瞧了瞧 sThreadLocal 是什么东西,搞来搞去大概就是这个意思:一个线程对应一个 Looper ,类似于通过键值对的方式保存在一个不为人知的地方(自己去看啦,不但可以存 Looper ,还可以存好多好多东西呢),所以通过 looper 可以获知宿主线程,通过线程也可以知道对应的 Looper ,而上面那条语句就是做了这样的一个事情,让他们两个之间建立非常亲密的一一对应的关系。简单的说 prepare ()的作用就是 new了一个 looper ,然后把它嫁给了当前所在的线程,永远不分开了。
Looper.loop() :这个方法和上面那个方式是一起用的,也是非常的亲密。它是干嘛的呢,瞧了瞧源代码,一堆代码原来就做了这样一件狗屁简单的事, loop 自己有一个messageQueue 变量,这个变量的意思就是消息队列,所以它装的尽是些 Message ,loop ()就无限循环不要命的去翻这个 messageQueue 里面的Message ,已经发现 Message,就把它给办了,怎么办了,这样一条语句给办了 msg.target.dispatchMessage(msg); 它这是干嘛啊,它的意思就是叫 message的老婆 handler( target)把它给办了,在 dispatch里面呢,先会执行 msg或者 handler的回调借口 callback,不空的话就执行这个就可以了,不去执行 handleMessage()。如果为空的话,就是我们平常用的情况,执行 handler的 handleMessage把这个 msg给办了。简单的说, loop就是启动循环,处理这个线程的 looper的消息队列里的消息。
Handler ,表面意思就是处理者,它就是消息的最终处理者。扒了 handler的衣服,嘿嘿看看好不好看啊?一看吓一跳,也不过如此。
handler 构造的时候,神不知鬼不觉地就去获取当前线程的 looper,原来 handler也是它的唯一(一一对应)。会出现 “Can’t create handler inside thread that has not called Looper.prepare()”);这个异常的原因,就是因为 handler找不到它亲爱的 looper了,要知道,一个线程被创建,必须手动 looper.prepare()去创建这个线程的 looper。那你会说 activity里面创建怎么就不会了,很明显啦, activity对应的是一个特殊线程 ActivityThread,系统已经执行了 looper.prepareMainLooper了还有 Looper.loop()了。明白这个异常的原因了吧,所以在一个自建的线程 Thread里,如果有 new Handler()这样的语句,必须在前面增加 Looper.prepare()来给这个 thread生成一个 looper,当然在最后也别忘了执行 Looper.loop()。

Handler.sendMessage 不要以为他把消息发给别个谁了,其实他就是把消息 Message 插到自己的messageQueue 里了,所以记着了, sendMessage 就是插入消息到队列中。还有很多 “ 乱七八糟” 的发送方法,无法就是啥时候插入到消息队列当中去嘛。
Handler.handleMessage 空方法,必须要自己实现。
Handler.dispatchMessage: asdf 分发消息,我是觉得没必要理解成是分发消息的意思,就是处理消息的意思。和上面什么区别,这个处理时先看看 message 或者handler 的 callback回调接口是否空的,不空就执行。前面 i 两个加上handleMessage ,只会执行其中一个,先后次序就是这里的文字先后顺序。
Message :本身就是一个链表,比较重要的地方就是只要 Message有实现 callback或者 handler里面有实现 callback的话, handler去 handleMessage处理消息的时候就会先执行 message的 callback或者先执行 handler的 callback。
还有一个比较重要的:它里面有一个静态变量 sPool也是 message它是一个 message池,存储着闲置的 message, obstain消息的方法都是从这个池子里获取。

事件分发流程

注意:一系列的事件处理,只有return true了才能不断的处理后续的action,如果返回false,则中断处理。

1.View的事件分发
简单的说:
事件是从View中的dispatchTouchEvent中分发下去,这个方法的实现适用于所有的视图组件(Button,TextView,ImageView,等等),但是在ViewGroup中重写了dispatchTouchEvent方法。

1.首先触发view所在的父布局的dispatchTouchEvent()方法。
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
return true;
}
if (onTouchEvent(event)) {
return true;
}
}
如果view本身注册的touchListener不为空,则先执行这个listener的onTouch方法,如果返回为true,则直接返回,不执行onTouchEvent(MotionEvent)方法。
2.否则,继续执行onTouchEvent()方法。在case Action_UP中执行了performClick(onclickListener监听)。在case Action_DOWN中执行了checkForLongPressed()。
在onTouchEvent中:
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
只要上句话成立,即可点击的话,就会返回onTouchEvent()就会返回true。
注意:在action_down的时候返回false将导致后续action不会得到执行。简单的说只有前一个action返回了true才会触发后一个action

ViewGroup事件分发
viewGroup必须复写dispatchTouchEvent,因为它不同于其他组件,它是一个view的容器,因此它有许多子布局,必须考虑到事件分发给子控件的问题。

DispatchEvent
1.dispatchTouchEvent方法开始需要判断intercepted的boolean值。这个值的意思是是否拦截事件。如果为true,即拦截事件,则不会考虑将事件分发给子布局。 intercepted = onInterceptTouchEvent(ev);
2.如果为false,且没有被cancel掉。则会考虑将事件派发给子布局,遍历子控件,通过坐标区域来确定应该派发给哪个子布局。
圣达菲
dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)

1.在上方法中 intercepted = onInterceptTouchEvent(ev);
2.来给intercepted赋值。

综上:
是View时:dispatchTouchEvent() onTouch(为true则直接返回) onTouchEvent(为true则返回true,为false则返回false,里面执行了click方法)

是ViewGroup时,ViewGroup.dispatchTouchEvent 在上述方法中intercepted = onInterceptTouchEvent() 为true,则执行子布局的dispatchTouchEvent

View。dispatchTouchEvent()。为false的话,子布局不能获得事件,TagertChild为null,在dispatchTransformedTouchEvent中,因为child等于null,执行super。dispatchTouchEvent,也就是
有纸质笔记 流程图