您的位置:首页 > 移动开发 > Android开发

Android之Handler源码深入分析

2015-08-18 12:33 423 查看
闲着没事,就来看看源码,看看源码的各种原理,会用只是简单的,知道为什么才是最牛逼的。

Handler源码分析那,从使用的步骤来边用边分析:

1.创建一个Handler对象:new Handler(getMainLooper(),this);

这是我常用的一个方式,getMainLooper是获取主线程的Looper,this则是实现CallBack的接口

看一下Handler的构造函数

public Handler() {

this(null, false);

}

public Handler(Callback callback) {

this(callback, false);

}

public Handler(Looper looper) {

this(looper, null, false);

}

public Handler(Looper looper, Callback callback) {

this(looper, callback, false);

}

@hide

public Handler(boolean async) {

this(null, async);

}

@hide

public Handler(Callback callback, boolean async) {

if (FIND_POTENTIAL_LEAKS) {

final Class<? extends Handler> klass = getClass();

if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&

(klass.getModifiers() & Modifier.STATIC) == 0) {

Log.w(TAG, "The following Handler class should be static or leaks might occur: " +

klass.getCanonicalName());

}

}

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;

}

@hide

public Handler(Looper looper, Callback callback, boolean async) {

mLooper = looper;

mQueue = looper.mQueue;

mCallback = callback;

mAsynchronous = async;

}

构造函数的最主要代码作用是参数的初始化赋值:

mLooper = looper;mQueue = looper.mQueue;mCallback = callback; mAsynchronous = async;

这四个参数是主要的参数了。

2.创建一个Message。 Message msg = handler.obtainMessage();

直接调用Handler的源码:

public final Message obtainMessage()

{

return Message.obtain(this);

}

Message中得源码:

public static Message obtain(Handler h) {

Message m = obtain();

m.target = h;

return m;

}

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();

}

这里Message是复用的概念,最大能够保持

private static final int MAX_POOL_SIZE = 50;

50个Message的对象。

sPool变量相当于当前的空的没有被使用的Message,通过转换,将当前这个空Message给返回出去。

Message在使用完之后会被回收的,在下面会有提到。

3.给Message赋值,并发送Message : msg.what = 100 ; handler.sendMessage(msg);

what是Message中得一个储值变量。

发送Message则在Handler中得最终指向是以下源码:

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

msg.target = this;

if (mAsynchronous) {

msg.setAsynchronous(true);

}

return queue.enqueueMessage(msg, uptimeMillis);

}

oK,sendMessage给发送给了MessageQueue类,看MessageQueue怎么处理的。

boolean enqueueMessage(Message msg, long when) {

...........

if (p == null || when == 0 || when < p.when) {

// New head, wake up the event queue if blocked.

msg.next = p;

mMessages = msg;

needWake = mBlocked;

} else {

// Inserted within the middle of the queue. Usually we don't have to wake

// up the event queue unless there is a barrier at the head of the queue

// and the message is the earliest asynchronous message in the queue.

needWake = mBlocked && p.target == null && msg.isAsynchronous();

Message prev;

for (;;) {

prev = p;

p = p.next;

if (p == null || when < p.when) {

break;

}

if (needWake && p.isAsynchronous()) {

needWake = false;

}

}

msg.next = p; // invariant: p == prev.next

prev.next = msg;

}

if (needWake) {

nativeWake(mPtr);

}

}

.......

}

截取了中间重要的代码说一下。这个是用来干嘛的??

其实就是用来排序的,我们知道的是Message有延迟的消息,延迟消息的时间都是不一样的,when是有大小的,将后执行的Message放到后面。

MessageQueue不是使用一个集合啊或者使用数组去存放的Message,真正排序的是Message的next变量,next变量存放的是当前Message的下一个Message。

发送之后就执行了一个原生的方法nativeWake,这个在这儿就不去探究了。

4.handler消息的处理回调Callback.

public static void loop() {

........

for (;;) {

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

.....

msg.target.dispatchMessage(msg);

.......

msg.recycleUnchecked();

}

......

}

这个那是Looper种的源码,loop就是循环取MessageQueue中得Message的方法。我去掉了代码,我们可以看到调用了Messa得target变量,这个变量存放的就是Handler,dispatchMessage就是用来分发Message的方法了。看DispatchMessage的源码:

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

这个就少了很多了啊!

看到了把,回调了callback。这样就完成了整个循环流程。

说一下上面的
msg.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++;

}

}

}

从方法名上可以知道这个是用来回收Message的。

在Message使用完毕之后,不是将MEssage对象销毁,而是存放起来,将其下次重复使用。

Handler运行大概流程就是这样的了。

Looper的类的源码分析,回头再解析。

Android开发交流群:417270671

我的github地址: https://github.com/flyme2012
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: