【yian_ http://blog.youkuaiyun.com/yianemail/article/details/50233373 转载烦请注明出处,尊重分享成果】
一直对Android中的消息处理机制比较模糊,恰好昨天做了一次Team知识分享,也就借此机会配合源码了解下消息处理机制,仅以博客记录。
1 前言
一:在分析别人的源码,一直都在workThread配合looper ,handler与uiThread交互互通Message。
二:对于很多初学者老说,大都是知其然而不知道其所以然的。
三:workThread与uiThread中间是怎样具体处理message的。
2 代码展示
你可能在刚开始接触Android开发时就会知道如下问题:
Android的UI时线程不安全的,如果在线程中更新UI会出现异常,导致程序崩溃;同时如果UI中做耗时操作又会导致臭名昭著的ANR异常。
为了解决如上这些问题,我们怎办呢?很简单,通常最经典常用的做法就是使用Android的异步消息机制实现即可(创建一个Message对象,使用Handler发送出去,然后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作)。所以说还是很有必要了解异步消息机制的Looper , Handler , Message等原理的。
一般我们在workThread通过handler发送meeesgae一般来说是这样的,首先是在workThread中发送消息,以及在uiThread中接受处理,于是,代码是这样的:
/**
* Created by luhuanju on 15/12/8.
*/
public class TwoActivity extends Activity {
static Handler handler=new Handler(){
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what=0){
//msg
}
}
};
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Message message=handler.obtainMessage(0);
message.obj="";//Object
handler.sendMessage(message);
}
}).start();
}
}
这就是我们平时用的Handler的过程,对于Handler异步处理的简单基础示例先说到这,接下来依据上面示例的写法分析原因与源代码原理。
3 分析Android异步消息机制源码
3-1异步消息概念流程图
handler.sendMessage —>MQ(looper不断循环取消息,一旦有新消息) —>handler(dispatchMessage);
3-2异步消息机制相关重要概念
3-2-1 Handler的工作原理
由例子代码很容易看出Handler 的工作主要包含发送消息以及处理消息,典型的发送一条消息snedMessage的源码如下:
/**
* Pushes a message onto the end of the message queue after all pending messages
* before the current time. It will be received in {@link #handleMessage},
* in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);//sendMessage继续调用了sendMessageDelayed
}
可以看到sendMessage继续调用sendMessageDelayed,继续查看
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
sendMessageDelayed 又继续调用了sendMessageAtTime,
sendMessageAtTime(Message msg, long uptimeMillis)方法有两个参数;msg是我们发送的Message对象,uptimeMillis表示发送消息的时间,uptimeMillis的值等于从系统开机到当前时间的毫秒数再加上延迟时间。
继续
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);