自己的理解,在handler.sendMessage(msg)的时候会将msg存入MessageQueue的队列,msg本身保存发送该meg的handler对象,Looper 循环从MessageQueue中取msg,回调发送该meg handler的 handleMessage方法。
Handler 是个工具,可以发送消息和处理消息
Message是个信息载体本身持有Handler对象
MessageQueue是个消息的仓库,所以的消息都存在这里,负责消息的存取。
Looper是个传送带,循环从MessageQueue中取Message。
1.Message 要传送的Message本身带有传输消息的武器Handler
public class Message{
//发送该msg的handler 用于回调使用
public Handler target;
public int what;
public Object obj;
}
2.Handler
public class Handler{
private MessageQueue mQueue;
private Looper mLooper;
//构造方法
public Handler(){
//Android中Looper的初始化是在ActivityThread中
//一个主ThreadLocal保存该线程的Looper
// 因为Looper需要循环消息队列,所以Looper中
//要持有MessageQueue的引用
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}
public void sendMessage(Message msg){
//1.msg持有handler对象是在这里赋值的
msg.target = this;
//2.发送消息的时候需要把消息进队
//所以需要MessageQueue对象
mQueue.enqueueMessage(msg)
}
public void dispatchMessage(Message msg){
handlerMessage(msg);
}
//提供回调方法
public void handlerMessage(Messgage msg){ }
}
3.Looper轮转
//final不能被继承
public final class Looper{
//ThreadLocal提供了set和get访问器用来访问
//与当前线程相关联的线程局部变量
public static ThreadLocal<Looper> sThreadLocal = ThreadLocal<Looper>();
MessageQueue mQueue;
//构造方法初始化MessageQueue
private Looper(){
mQueue = new MessageQueue();
}
//生成Looper对象
public static void prepare(){
if(sThreadLocal.get()!=null){
throw new RuntimeException("only one looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
//获取Looper对象
public static Looper myLooper(){
return sThreadLocal.get();
}
//循环消息队列
public static void loop(){
Looper me = myLooper();
if(me==null){
throw new RuntimeException("on looper ");
}
MessageQueue queue = me.mQueue;
for(;;){
Message msg = queue.next();
if(msg==null){
continue;
}
msg.target.dispatchMessage();
}
}
}
4.MessageQueue简单实现,生产消费,并发操作
public class MessageQueue{
//存储消息
Message[] items;
//存消息的下标
int putIndex;
//取消息下标
int takeIndex;
//计数
int count;
/*线程通信用到的变量*/
private Lock lock;
private Condition notEmpty;
private Condition notFull;
public MessageQueue(){
this.items = new Message[50];
this.lock = new ReentrantLock();
this.notEmpty = lock.newCondition();
this.notFull = lock.newCondition();
}
//消息存入队列
public void enqueueMessage(Message msg){
try{
lock.lock();
while(count==item.length){
try{
//阻塞等待不满
notFull.await();
}catch(Exception e){
e.printStackTrace();
}
}
items[putIndex] = msg;
putIndex = (++putIndex==items.length)?0:putIndex;
count++;
//通知不为空
notEmpty.signalAll();
}finally{
lock.unlock();
}
}
//取消息
public Message next(){
Message msg = null;
try{
lock.lock();
while(count==0){
try{
//等待不为空
notEmpty.await();
}catch(Exception e){
e.printStackTrace();
}
}
msg = items[takeIndex];
items[takeIndex] = null;
takeIndex = (++takeIndex==items.length)?0:takeIndex;
count--;
notFull.signalAll();
}finally{
lock.unlock();
}
return msg;
}
}
4.客户端调用
public class Client{
public static void main(String[] args){
Looper.prepare();
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
System.out.println(Thread.currentThread().getName()+
",receive:"+
msg.toString());
}
};
for(int i=0;i<50;i++){
new Thread(){
@Override
public void run(){
while(true){
Message msg = new Message();
msg.what = 1;
msg.object = Thread.currentThread().getName()+
",send message:"+UUID.randomUUID().toString();
handler.sendMessage(msg.toString());
try{
Thread.sleep(1000);
}catch(Exception e){e.printStackTrace();}
}
}
}.start();
}
Looper.loop();
}
}
网友评论