异步消息处理线程是指线程启动后会进入一个无限循环,每循环一次,从内部的消息队列里面取出一个消息,并回调相应的消息处理函数。一般在任务常驻,比如用户交互任务的情况下使用异步消息处理线程。
之前在Android中Handler原理里面研究过android里实现异步消息处理线程的方式,基本逻辑如图所示
今天就用java将其简单的模拟出来加深印象,下面的类图是用工具导出的,不太正规,不过能大概看出类之间的关系
Message类:消息类
public class Message {
public int what;
public Object obj;
public Handler target;
}
Looper类:用来将普通的线程变为异步消息循环的类,维护了一个消息队列。每个线程有且仅有Looper对象,且是线程封闭的,每个线程都有自己的一份拷贝。
public class Looper {
private MessageQueue queue;
private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
public Looper() {
queue = new MessageQueue();
}
public static void prepare(){
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper can be created per thread");
}
sThreadLocal.set(new Looper());
}
public static Looper myLooper() {
return sThreadLocal.get();
}
public static MessageQueue myQueue() {
return myLooper().queue;
}
public static void loop(){
while(true){
Message msg = myQueue().deQueueMessage();
if (msg == null) {
continue;
}else {
msg.target.dispatchMessage(msg);
}
}
}
}
MessageQueue 类:消息队列,按照先进先出的原则从队列里面取出消息Message
public class MessageQueue {
private Queue<Message> queue = new LinkedList<Message>();
public synchronized void enqueueMessage(Message msg){
queue.offer(msg);
}
public synchronized Message deQueueMessage(){
if (queue.isEmpty()) {
return null;
}
return queue.poll();
}
}
Handler类:一般不直接操作队列,通过handler往消息队列里面加入Message对象。并且暴露handlerMessage方法让程序员重写达到自己的处理的目的。
public class Handler {
private MessageQueue queue;
public Handler(){
queue = Looper.myQueue();
}
public void sendMessage(Message msg){
msg.target = this;
queue.enqueueMessage(msg);
}
public void dispatchMessage(Message msg) {
handleMessage(msg);
}
public void handleMessage(Message msg){}
}
Main 类:程序运行的启动类
public class Main {
public static void main(String[] args) {
Looper.prepare();
TestInterface test = new Test();
test.onCreate();
Looper.loop();
}
}
TestInfo接口:规范了测试的一个接口
public interface TestInterface {
void onCreate();
}
Test 类:暴露出来的唯一的需要程序员填写代码的类我们在一个定时器里面每一秒钟发送一条消息到主线程,并将其显示出来
public class Test implements TestInterface{
private static SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
if (msg.what == 1) {
System.out.println("handler--->" + (String)msg.obj);
}
};
};
@Override
public void onCreate() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 1;
msg.obj = "test" + sdf.format(new Date());
handler.sendMessage(msg);
}
}, 0,1000);
}
}
测试结果如下:
handler—>test21:32:43
handler—>test21:32:44
handler—>test21:32:45
handler—>test21:32:46
handler—>test21:32:47
handler—>test21:32:48
handler—>test21:32:49
…….
android子线程中不能更新UI,一般都是通过消息机制在UI线程中更新UI的。
原文地址:http://blog.csdn.net/cauchyweierstrass/article/details/49338721