自己动手写消息机制

   首先,我们先别管Android中的消息机制,我们先来看一个需求:

   在主线程中启动一个子线程去做一些事情,我希望子线程在做完这些事情后唤醒主线程来做一些相应的动作。

   先想想怎么实现这个功能。直接在子线程回调一个接口?显然不行!

   要让主线程感知到子线程的事情是否做完了。一般来说,就是在子线程完成事情后发送一些消息给主线程,让主线程知道子线程已经完成了工作,然后主线程去做相应的处理。这样一来,主线程就要变成一个死循环,无限循环的从消息队列中获取从子线程来的消息,并处理。

   图中,主线程是一个轮询线程,主线程要做的事情就是,不断从消息队列中获取消息,并做处理。子线程处理完相关的业务之后,发送一个消息到消息队列中。整个过程是异步的。

   同步:主线程启动一个子线程,在子线程执行过程中,主线程等待子线程完成后才继续往下运行

   异步:主线程启动一个子线程,在子线程执行过程中,主线程也在运行

 

   我们建立一个Java项目,简单模仿一下Android的消息机制

 Looper是用来将线程变成一个轮询线程

 

package com.zhanjixun;

import java.util.HashMap;
import java.util.Map;

public class Looper {

	private static Map<Long, Looper> mLoopers = new HashMap<Long, Looper>();

	private MessageQueue mQueue = new MessageQueue();

	private Looper() {

	}

	public static void prepare() {
		long id = Thread.currentThread().getId();
		if (mLoopers.get(id) != null) {
			throw new RuntimeException("这线程的Looper已经调用prepare()");
		}
		mLoopers.put(id, new Looper());
	}

	public static void loop() {
		while (true) {
			Message next = myLooper().getMessageQueue().next();
			if (next != null) {
				if (next.getTarget() == null) {
					return;
				} else {
					next.getTarget().handlerMessage(next);
				}
			}
		}
	}

	public static Looper myLooper() {
		Looper looper = mLoopers.get(Thread.currentThread().getId());
		if (looper == null) {
			throw new RuntimeException(Thread.currentThread().getName()
					+ "线程的Looper还没有调用prepare()");
		}
		return looper;
	}

	public MessageQueue getMessageQueue() {
		return mQueue;
	}
}


其中的MessageQueue是用来管理Message的队列数据结构,先进先出原则

 

 

package com.zhanjixun;

import java.util.LinkedList;

public class MessageQueue {

	private LinkedList<Message> mMsgs = new LinkedList<>();

	public void push(Message msg) {
		System.out.println("有消息进队列-->>>" + msg.toString());
		mMsgs.add(msg);
	}

	public Message next() {
		if (mMsgs.size() > 0) {
			Message removeFirst = mMsgs.removeFirst();
			System.out.println("有消息从队列被取出<<<---" + removeFirst.toString());
			return removeFirst;
		}
		return null;
	}

}

Message类是对要发送的消息的一个封装

 

 

package com.zhanjixun;

public class Message {
	public int what;
	public Object obj;
	private Handler target;

	public Handler getTarget() {
		return target;
	}

	public void setTarget(Handler target) {
		this.target = target;
	}

}


Handler负责发送Message以及轮询线程回调

 

 

package com.zhanjixun;

/**
 * Handler负责发送Message以及轮询线程回调
 * 
 * @author doudian
 *
 */
public class Handler {

	private Looper myLooper;

	/**
	 * 创建Handler一定要在轮询线程中创建,因为创建的时候需要获取轮询线程的Looper
	 */
	public Handler() {
		myLooper = Looper.myLooper();
	}

	public void sendMessage(Message message) {
		message.setTarget(this);
		myLooper.getMessageQueue().push(message);
	}

	public void handlerMessage(Message message) {

	}
}

 

 

 

 

 

 


   最后在Main方法中调用试试看成果

 

 

 

 

package com.zhanjixun;


public class Main {

	public static void main(String[] args) {
		Looper.prepare();
		Handler handler = new Handler() {
			@Override
			public void handlerMessage() {
				System.out.println(" doing something in "
						+ Thread.currentThread().getName() + " thread");
			}
		};
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println(" doing something in "
						+ Thread.currentThread().getName() + " thread");
				handler.sendMessage(new Message());
			}
		}).start();
		Looper.loop();
		throw new RuntimeException("主线程不小心停止了!");
	}
}

 

 

运行结果

 

源代码:http://download.csdn.net/detail/zhanjixun/9582075
   

   写到这里大概就能明白整个消息机制的原理了:就是将主线程(也可以是其他子线程)变成一个死循环的线程,不断从队列中获取消息并处理;子线程处理一些业务,处理完毕就发送一个消息到消息队列中。

 

 

   有空在分析一下Android中消息机制的源码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值