一. android studio中使用
1.创建消息
1>通过Message类的obtain获取
Message message = Message.obtain(); //不含参数
Message message = Message.obtain(h); //传进handler
Message message = Message.obtain(h,callback); //传进handler,callback
Message message = Message.obtain(h,what); //传进handle,what
2>通过Handler类的obtainMessage获取,实际也是调用Message中的obtain方法,区别在于此时的handler为它本身
Message msg=handler.obtainMessage();
Message msg=handler.obtainMessage(what);//传进what
3>设置Message参数
message.what=10; //消息类型
Bundle bundle =new Bundle();
bundle.putString("name","jack");
message.setData(bundle);//传进数据
message.setTarget(mHandlerT);//设置处理消息的目标handler
2.发送消息
调用Handler类中的sendMessage发送
mHandler.sendMessage(message); //立即发送
mHandler.sendMessageDelayed(message,1000); //延迟1s发送
mHandler.dispatchMessage(message);//分发消息,由传进的callback处理
3.处理消息
在继承Handler的类中重写handleMessage方法
public void handleMessage(Message msg) {
Log.d(TAG,"receive message "+msg);
tv.setText(msg.getData().getString("name"));
switch (msg.what){ //一般通过msg.what来判断处理什么消息
case 1:break;
case 2: break;
}
}
二.源码分析
代码路径:framework/base/core/java/android/os/
1>创建消息
/获取Message对象
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) { //相当于单向链表,sPool指向表头元素,每次取出表头元素
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
//回收Message对象
void recycleUnchecked() { 由recycle调用
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) { //最大容量为50
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
//Message中的参数
public int what //一般用于指代消息类型
public int arg1;
public int arg2; //参数一,参数二一般不怎么使用,而是使用setData(Bundle)传进数据
Handler target;//处理消息的Handler,可通过setTarget设置
2>发送消息
最终均会调用到sendMessageAtTime
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0); //延迟为0
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//当前时间加延迟时间
}
public boolean sendMessageAtTime(@NonNull 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(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this; //target设为本身,即Handler对象
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);//MessageQueue
}
查看MessageQueue中的enqueueMessage,主要逻辑如下
boolean enqueueMessage(Message msg, long when) {
。。。
msg.markInUse();
msg.when = when;
Message p = mMessages; //报存的头结点
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; //尾插法,每次尾部插入一个msg
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
3>消息怎么传递到Handler的
在handleMessage中添加堆栈打印,打印如下
在主线程中通过Looper.loop来处理消息
public static void loop() {
。。。
for (;;) {
Message msg = queue.next(); // might block ,重点关注,取出MessageQueue中的消息
msg.target.dispatchMessage(msg); //分发消息
msg.recycleUnchecked();
}
}
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);//处理消息
}
}
HandlerThread.run
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
MessageQueue中的next
Message next() {
。。。
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
if (mQuitting) {
dispose();
return null;
}
}
三.Registrant和RegistrantList
常见于rilj中
比如UiccController中处理EVENT_ICC_STATUS_CHANGED,其获取消息为以下代码
mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, i);
public void registerForIccStatusChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mIccStatusChangedRegistrants.add(r); //mIccStatusChangedRegistrants为 RegistrantList对象
}
//RegistrantList中的add
add(Registrant r)
{
removeCleared();
registrants.add(r);//registrants为ArrayList对象
}
发送消息时调用RegistrantList中的 notifyRegistrants
notifyRegistrants()
{
internalNotifyRegistrants(null, null);
}
internalNotifyRegistrants (Object result, Throwable exception)
{
for (int i = 0, s = registrants.size(); i < s ; i++) {
Registrant r = (Registrant) registrants.get(i);
r.internalNotifyRegistrant(result, exception);
}
}
//Registrant
internalNotifyRegistrant (Object result, Throwable exception)
{
Handler h = getHandler();
if (h == null) {
clear();
} else {
Message msg = Message.obtain();
msg.what = what;
msg.obj = new AsyncResult(userObj, result, exception);
h.sendMessage(msg);//调用Handler中的sendMessage 发送消息
}
}
后续逻辑与第二部分相同