looper源码分析
public final class Looper{
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
final MessageQueue mQueue;
final Thread mThread;
private Looper(boolean quitAllowed) {
//looper 管理MessageQueue
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
public static void prepare() {
prepare(true);
}
//说明一个线程 只能有一个looper
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
//代码有省略
public static void loop(){
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for(;;){
Message msg = queue.next();
if(msg == null){
//消息空了挂起
return;
}
//looper 从message中取出消息,交给handler处理。 looper
msg.target.dispatchMessage(msg);
...
//释放消息
msg.recycleUnchecked();
}
}
//获取当前线程的looper
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//Quits the looper.
public void quit() {
mQueue.quit(false);
}
//Quits the looper safely.
public void quitSafely() {
mQueue.quit(true);
}
}
总结:每个线程只有一个looper,这个looper轮询管理该线程的MessageQueue。
Looper常用方式
class LooperThread extends Thread{
public Handler mHandler;
public void run(){
Looper.prepare();
mHandler = new Handler(){
public void handleMessage(Message msg){
}
};
Looper.loop();
}
}
Handler的设计
Handler源码分析
//回调调用
public interface Callback {
public boolean handleMessage(Message msg);
}
//接收消息方法
public void handleMessage(Message msg) {
}
//looper 循环messageQueue后, 出队后的数据通过此方法执行
//msg.callback 是runable, 这个方法执行的顺序问题,具体使用考虑场景
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
//传入接口回调,会优先拦截
if (mCallback.handleMessage(msg)) {
return;
}
}
//new handler 实现接收消息的方法
handleMessage(msg);
}
}
public Handler(Callback callback, boolean async){
...
//此处调用 可以看出初始化Handler前必须先调用 Looper.prepare()
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
//obtainMessage 重载方法 获取Messa实例, 运用享元模式设计模式
public final Message obtainMessage()
{
return Message.obtain(this);
}
public final Message obtainMessage(int what)
{
return Message.obtain(this, what);
}
...
//Returns true if the Runnable 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 post(Runnable r)
{
//调用getPostMessage得到Message
return sendMessageDelayed(getPostMessage(r), 0);
}
//直接message或者runnable形式,最后都是通过enqueueMessage加入MessageQueue
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
//runnable 包装成Message
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//加入MessageQueue队列
return queue.enqueueMessage(msg, uptimeMillis);
}
//重队列移除对应的消息
public final void removeCallbacks(Runnable r)
{
mQueue.removeMessages(this, r, null);
}
//等相关的移除方法
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
总结: Handler关联单一线程和MessageQueue;处理looper轮询分发的消息,和将消息加入MessageQueue中。
Message的设计分析
用对象池思想,运用享元模式,采用链表形式缓存Message实例,方便快速获取。
Message源码分析
public final class Message implements Parcelable{
// sometimes we store linked lists of these things
/*package*/ Message next;
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
//存在缓存则从缓存链表获取头, 并做相应的链表指向修改,没有则new一个
//obtain重载的的方法 都是如此思想获取
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it "
+ "is still in use.");
}
return;
}
recycleUnchecked();
}
//释放,缓存个数没到上线则加入缓存池中
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = -1;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
}
网友评论