Android源码之Handler(三)

public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
[// mQueue = looper.mQueue
这里可以看出,Handler类的MessageQueue成员变量mQueue其实就是Looper内部的MessageQueue变量。
]// mQueue = looper.mQueue
mCallback = callback;
mAsynchronous = async;
}
[// public Handler(Looper looper, Callback callback, boolean async)
这个重载版本的构造函数的实现就是初始化Handler的几个成员变量。这几个成员变量的定义如下:
final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
[// final Callback mCallback
mCallback是Handler的Callback. 其实Message中会有一个Runnable类型的成员变量callback,这里为什么又要给Handler来定义一个Callback的成员变量呢?
Callback接口定义在Handler内部:
public interface Callback {
public boolean handleMessage(Message msg);
}
]// final Callback mCallback
final boolean mAsynchronous;
[// final boolean mAsynchronous
mAsynchronous表示Hanlder是否是异步的?在我们的认识中,Handler就是按照顺序来处理消息的, 这难道不是Handler的作用么?难道还可以异步的处理消息么?
]// final boolean mAsynchronous
由此可见,每一个Handler内部维护了一个Looper,而每一个Looper中又维护了一个MessageQueue.
这里我们就来看一下Looper的实现:

]// public Handler(Looper looper, Callback callback, boolean async)
Handler的一系列的构造函数中,其实最重要的就是两个:Handler(Callback callback, boolean async)和Handler(Looper looper, Callback callback, boolean async).
]// Handler的构造函数

当通过Handler构造函数得到了Handler对象之后, 会调用obtainMessage来得到一个Message对象. Android推介使用Handler的obtainMessage函数来得到一个Message对象,而不是直接构造一个Message对象, 为什么呢?
同样Handler类也提供了一系列的obtainMessage函数, 我们看一看obtainMessage函数的实现:
[// obtainMessage函数
public final Message obtainMessage()
{
return Message.obtain(this);
}
public final Message obtainMessage(int what)
{
return Message.obtain(this, what);
}
public final Message obtainMessage(int what, Object obj)
{
return Message.obtain(this, what, obj);
}
public final Message obtainMessage(int what, int arg1, int arg2)
{
return Message.obtain(this, what, arg1, arg2);
}
public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
{
return Message.obtain(this, what, arg1, arg2, obj);
}
从以上代码也可以看出, Handler的obtainMessage函数其实是调用Message的obtain函数来实现的. 我们看一下Message类的obtain函数的实现:
[// Message类的obtain函数
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;

return m;
}
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;

return m;
}
public static Message obtain(Handler h, int what) {
Message m = obtain();
m.target = h;
m.what = what;

return m;
}
public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.obj = obj;

return m;
}
public static Message obtain(Handler h, int what, int arg1, int arg2) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;

return m;
}
public static Message obtain(Handler h, int what,
int arg1, int arg2, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
m.obj = obj;

return m;
}

Message类同样提供了一系列的obtain的重载函数, 不过大同小异, 都是先调用obtain()函数得到一个Message对象,然后初始化这个Message对象,并返回该Message对象。
我们分析一下Message类的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;
}
}
[// synchronized (sPoolSync)
上面这段代码就是从缓存中取Message。
其中定义了几个成员变量,分别为:
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
这些变量的作用都很明确. 注意:这些成员变量都是statics的。
]// synchronized (sPoolSync)
return new Message();
}
[// public static Message obtain()
Message的obtain函数的作用得到一个Message变量. 其实Android为Handler维护了一个Message的缓存, 调用obtain函数会首先尝试从缓存中取Message对象,而不是每次就构造一个Message对象。
这就是为什么推荐使用obtain函数来得到一个Message对象的原因。
我们简单来看一下Message的几个重要的成员变量:
public int what;
what成员变量是为了区分不同的Message.
public int arg1;
public int arg2;
public Object obj;
public Messenger replyTo;
public int sendingUid = -1;
/*package*/ static final int FLAG_IN_USE = 1 << 0;
/*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;
/*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;

/*package*/ int flags;

/*package*/ long when;
when指示该消息需要被处理的时间戳
/*package*/ Bundle data;

/*package*/ Handler target;
target是最重要的成员变量. Android系统就是通过target找到这个Message所属于的Handler对象,然会调用这个Handler对象的handleMessage函数来处理该消息的
/*package*/ Runnable callback;
/*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;
private static boolean gCheckRecycle = true;
]// public static Message obtain()
]// Message类的obtain函数
]// obtainMessage函数
经过上面的源码分析,我们可以明白Handler, Looper, MessageQueue和Message个关系了,也理解了这四者是如何配合从而完成Handler机制的。
下面我们分析一下发消息的过程,这主要是通过调用Handler的sendMessage和post函数完成的. Handler提供了一系列的send和post函数:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
[// sendMessageDelayed(getPostMessage(r), 0)
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
]// sendMessageDelayed(getPostMessage(r), 0)
}
public final boolean postAtTime(Runnable r, long uptimeMillis)
{
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
{
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
[// return sendMessageAtTime(getPostMessage(r, token), uptimeMillis)
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
]// return sendMessageAtTime(getPostMessage(r, token), uptimeMillis)
}
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
public final boolean postAtFrontOfQueue(Runnable r)
{
return sendMessageAtFrontOfQueue(getPostMessage(r));
}
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public final boolean sendMessageAtFrontOfQueue(Message msg) {
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, 0);
}
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);
}
上面这么多的函数(post用于发送Runnable, send用于发送Message),其实都是很相似的。大致过程都成先得到一个Message, 然后调用enqueueMessage函数插入到消息队列中。
我们分析一下enqueueMessage函数的实现:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
[// return queue.enqueueMessage(msg, uptimeMillis);
这里会调用MessageQueue的enqueueMessage函数来将Message插入到队列中,MessageQueue的enqueueMessage函数的实现如下:
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}

synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
msg.recycle();
return false;
}

msg.markInUse();
[// msg.markInUse()
将消息标记为正在使用
void markInUse() {
flags |= FLAG_IN_USE;
}
]// msg.markInUse()
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
[// if (p == null || when == 0 || when < p.when)
将消息插入到头部,这时候要唤醒Looper
]// if (p == null || when == 0 || when < p.when)
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
[// else
将消息插入到队列的中间
]// else
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;
}

// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
[// nativeWake(mPtr)
这里调用nativeWake函数来唤醒Looper, 这也是个native函数,实际上调用的是android_os_MessageQueue.cpp中定义的android_os_MessageQueue_nativeWake函数。
android_os_MessageQueue_nativeWake的定义如下:
static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
return nativeMessageQueue->wake();
[// return nativeMessageQueue->wake()
这里调用的是NativeMessageQueue的wake函数.
void NativeMessageQueue::wake() {
mLooper->wake();
[// mLooper->wake()
这里又调用了C++层的wake函数,
void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ wake", this);
#endif

ssize_t nWrite;
do {
nWrite = write(mWakeWritePipeFd, "W", 1);
} while (nWrite == -1 && errno == EINTR);

if (nWrite != 1) {
if (errno != EAGAIN) {
ALOGW("Could not write wake signal, errno=%d", errno);
}
}
}
可以看到C++层的wake函数就是用mWakeWritePipeFd向管道里发送一个"w"字符,这样就会将epoll_wait函数来唤醒。
]// mLooper->wake()
}
]// return nativeMessageQueue->wake()
}
]// nativeWake(mPtr)
}
}
return true;
}
]// return queue.enqueueMessage(msg, uptimeMillis);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值