研究通了Handler的原理,自己手写了个简易的Handler。 此处的Queue直接采用了java里现成的LinkedBockingQueue
XHandler: 根据Android Handler原理手写了个简易的Handler
Handler
class XHandler {
XLooper mLooper;
XMessageQueue mQueue;
public XHandler() {
this(XLooper.myLooper());
}
public XHandler(XLooper looper) {
mLooper = looper;
mQueue = looper.mQueue;
}
void dispatchMessage(XMessage msg) {
if (msg.callback != null) {
msg.callback.run();
} else {
handleMessage(msg);
}
}
void sendMessage(XMessage msg) {
msg.target = this;
mQueue.enqueueMessage(msg);
}
void postMessage(Runnable runnable) {
XMessage msg = new XMessage();
msg.callback =runnable;
sendMessage(msg);
}
void handleMessage(XMessage msg) {
}
}
Looper
package team.todos.test.handler;
import android.util.Log;
class XLooper {
private static final String TAG = "XLooper";
XMessageQueue mQueue;
Thread mThread;
private static ThreadLocal<XLooper> sThreadLocal = new ThreadLocal<>();
XLooper() {
this(true);
}
public static void prepare() {
prepare(true);
}
private XLooper(boolean quitAllowed) {
mQueue = new XMessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new XLooper(quitAllowed));
}
public static XLooper myLooper() {
return sThreadLocal.get();
}
public static void loop() {
final XLooper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final XMessageQueue queue = me.mQueue;;
for (;;) {
XMessage msg = queue.next();
if (queue == null) {
break;
}
msg.target.dispatchMessage(msg);
}
Log.e(TAG, "Loop END");
}
public void quit(){
mQueue.quit();
}
}
MessageQueue
package team.todos.test.handler;
import java.util.concurrent.LinkedBlockingQueue;
class XMessageQueue {
LinkedBlockingQueue<XMessage> mQueue = new LinkedBlockingQueue<>();
public XMessageQueue(boolean quitAllowed) {
}
public XMessage next() {
try {
return mQueue.take();
} catch (InterruptedException e) {
return null;
}
}
public void enqueueMessage(XMessage msg) {
try {
mQueue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void quit() {
mQueue.clear();
}
}