美文网首页
Handler源码简单解析

Handler源码简单解析

作者: 卿卿奈良 | 来源:发表于2017-10-10 02:39 被阅读0次

了解handler运行原理首先从android的main函数开始:

Looper

在函数初始调用prepareMainLooper(),


...

Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();

thread.attach(false);

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

if (false) {

Looper.myLooper().setMessageLogging(new

LogPrinter(Log.DEBUG, "ActivityThread"));

}

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");

}

查看Looper的函数,prepare创建了一个Looper对象;

public static void prepareMainLooper() {

prepare(false);

synchronized (Looper.class) {

if (sMainLooper != null) {

throw new IllegalStateException("The main Looper has already been prepared.");

}

sMainLooper = myLooper();

}

}

private static Looper sMainLooper;  // guarded by Looper.class

sMainLooper是Looper类保护的一个静态变量,如果sMainLooper为null,把我们得到的Looper对象赋值给sMainLooper,否则抛出异常。

ThreadLocal里面使用ThreadLocalMap内部类保存了一个map集合,此处放置的是looper。

可以看出prepare函数是用来create Looper的,如果当前线程已经存在Looper对象的话,

throw exception;否则的话new一个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 @Nullable Looper myLooper() {

return sThreadLocal.get();

}

looper的初始化方法,quitAllowed猜测是不允许退出的意思。可以看出在Looper的初始化过程中创建了一个消息队列,同时和当前线程进行了绑定。

private Looper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mThread = Thread.currentThread();

}

Looper创建好以后,执行Looper.loop();

首先拿到我们创建号的looper,同时根据当前的Looper得到MessageQueue对象,开始一个无限循环,

不断的从queue里取消息,同时通过msg.target执行消息分发流程。

public static void loop() {

final Looper me = myLooper();

if (me == null) {

throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

}

final MessageQueue queue = me.mQueue;

...

for (;;) {

Message msg = queue.next(); // might block

if (msg == null) {

// No message indicates that the message queue is quitting.

return;

}

msg.target.dispatchMessage(msg);

}

}

Handler

通常创建Handler有一下两种方式,如果需要传CallBack的话需要implements它的handleMessage()方法。

public Handler() {

this(null, false);

}

public Handler(Callback callback) {

this(callback, false);

}

public interface Callback {

public boolean handleMessage(Message msg);

}

这种调用方式最后都会调用到

public Handler(Callback callback, boolean async) {

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;

}

在这个方法里mLooper是得到当前线程的Looper对象,进而得到Looper中MessageQueue对象;

在loop()方法最后有一句msg.target.dispatchMessage(msg),根据Message.class中

Handler target;知道在这里调用了Handler的dispatchMessage(msg):

如果callback != null的时候msg是通过post(r)得到的,mCallback是初始化Handler的时候传入的,如果存在的话则消息的处理由开发者自己处理,否则使用Handler自身的handleMessage(msg),同时,Handler自身对于handlerMessage(msg)并没有做任何的处理,而是在subClass里面去处理逻辑。

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

相关文章

网友评论

      本文标题:Handler源码简单解析

      本文链接:https://www.haomeiwen.com/subject/erbmyxtx.html