博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MessageQueen源码分析
阅读量:3932 次
发布时间:2019-05-23

本文共 12976 字,大约阅读时间需要 43 分钟。

一、由于MessageQueen是用来存放Message的,那么是如何存储Message的呢?

由于Handler使用Post()方法将Message传递到MessageQueen中,在MessageQueen中会使用enqueueMessage()方法存储Message,其实现的方式是通过单链表的数据结构来存储消息列表

boolean enqueueMessage(Message msg, long when) {
... synchronized (this) {
... msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) {
msg.next = p; mMessages = msg; needWake = mBlocked; } 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; prev.next = msg; } if (needWake) {
nativeWake(mPtr); } } return true;}

整个进队列的过程就完了,这里做了哪几件事:

1、首先判断消息队列里有没有消息,没有的话则将当前插入的消息作为队头,并且这时消息队列如果处于等待状态的话则将其唤醒

2、若是在中间插入,则根据Message创建的时间进行插入

二、既然MessageQueen存了消息之后,是如何提供取出来的方法的呢?

我们知道存消息是Handler存进来的,那么取消息就应该是Looper中取了,从Looper的源码可以看出,消息就是在Looper中取出的,其实现是用MessageQueen里面的next()方法

Message next() {
...... int nextPollTimeoutMillis = 0; for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands(); } // nativePollOnce方法在native层,若是nextPollTimeoutMillis为-1,这时候消息队列处于等待状态。    nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) {
final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) {
do {
prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } //按照我们设置的时间取出消息 if (msg != null) {
if (now < msg.when) {
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else {
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 {
// 如果消息队列中没有消息,将nextPollTimeoutMillis设为-1,下次循环消息队列则处于等待状态 nextPollTimeoutMillis = -1; } //退出消息队列,返回null,这时候Looper中的消息循环也会终止。 if (mQuitting) {
dispose(); return null; } ...... } ..... }}

三、在MessageQueen存消息的媒介是通过Message对象,那这个Message对象又是什么呢?

Message就是用来存储Message中各种信息的Bean对象,直接上源码:

public final class Message implements Parcelable {
//消息标签 public int what; //携带参数 public int arg1; //携带参数 public int arg2; //携带对象 public Object obj; //IPC的通信返回 public Messenger replyTo; public int sendingUid = -1; //消息使用标志 static final int FLAG_IN_USE = 1 << 0; static final int FLAG_ASYNCHRONOUS = 1 << 1; static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE; int flags; //执行时间 long when; //传递数据 Bundle data; //消息分发目标 Handler target; //消息回调 Runnable callback; //下一个消息 // sometimes we store linked lists of these things Message next; //同步锁 public static final Object sPoolSync = new Object(); //指向回收的Message 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() {
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(); } //消息内容传进去,赋值返回 public static Message obtain(Message orig) {
Message m = obtain(); m.what = orig.what; m.arg1 = orig.arg1; m.arg2 = orig.arg2; m.obj = orig.obj; m.replyTo = orig.replyTo; m.sendingUid = orig.sendingUid; if (orig.data != null) {
m.data = new Bundle(orig.data); } m.target = orig.target; m.callback = orig.callback; return m; } //指定目标target public static Message obtain(Handler h) {
Message m = obtain(); m.target = h; return m; } //指定目标target和Runable执行体 public static Message obtain(Handler h, Runnable callback) {
Message m = obtain(); m.target = h; m.callback = callback; return m; } //指定target和消息标签what public static Message obtain(Handler h, int what) {
Message m = obtain(); m.target = h; m.what = what; return m; } //赋值返回Message public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain(); m.target = h; m.what = what; m.obj = obj; return m; } //赋值返回Message 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; } //赋值返回Message 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; } //5.0以下需要指定标签gCheckRecycle为false,默认为true public static void updateCheckRecycle(int targetSdkVersion) {
if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
gCheckRecycle = false; } } //双重检查通过就释放Message public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } 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 public void copyFrom(Message o) {
this.flags = o.flags & ~FLAGS_TO_CLEAR_ON_COPY_FROM; this.what = o.what; this.arg1 = o.arg1; this.arg2 = o.arg2; this.obj = o.obj; this.replyTo = o.replyTo; this.sendingUid = o.sendingUid; if (o.data != null) {
this.data = (Bundle) o.data.clone(); } else {
this.data = null; } } //获取执行时间 public long getWhen() {
return when; } //设置执行target public void setTarget(Handler target) {
this.target = target; } //获取执行target public Handler getTarget() {
return target; } //获取回调(Handler-post调用的) public Runnable getCallback() {
return callback; } /** @hide */ public Message setCallback(Runnable r) {
callback = r; return this; } //获取Bundle传递的数据 public Bundle getData() {
if (data == null) {
data = new Bundle(); } return data; } //有点像getData(),不过他是有什么返回什么,null就返回null public Bundle peekData() {
return data; } //设置Bundle数据 public void setData(Bundle data) {
this.data = data; } //设置what标签 public Message setWhat(int what) {
this.what = what; return this; } //发送给目标target public void sendToTarget() {
target.sendMessage(this); } //判断消息是异步的吗?我们在Handler解析的时候 public boolean isAsynchronous() {
return (flags & FLAG_ASYNCHRONOUS) != 0; } //设置消息为异步 public void setAsynchronous(boolean async) {
if (async) {
flags |= FLAG_ASYNCHRONOUS; } else {
flags &= ~FLAG_ASYNCHRONOUS; } } //标签消息是否将被使用 boolean isInUse() {
return ((flags & FLAG_IN_USE) == FLAG_IN_USE); } //设置标签消息为将被使用 void markInUse() {
flags |= FLAG_IN_USE; } //构建一个Message public Message() {
} @Override public String toString() {
return toString(SystemClock.uptimeMillis()); } String toString(long now) {
StringBuilder b = new StringBuilder(); b.append("{ when="); TimeUtils.formatDuration(when - now, b); if (target != null) {
if (callback != null) {
b.append(" callback="); b.append(callback.getClass().getName()); } else {
b.append(" what="); b.append(what); } if (arg1 != 0) {
b.append(" arg1="); b.append(arg1); } if (arg2 != 0) {
b.append(" arg2="); b.append(arg2); } if (obj != null) {
b.append(" obj="); b.append(obj); } b.append(" target="); b.append(target.getClass().getName()); } else {
b.append(" barrier="); b.append(arg1); } b.append(" }"); return b.toString(); } void writeToProto(ProtoOutputStream proto, long fieldId) {
final long messageToken = proto.start(fieldId); proto.write(MessageProto.WHEN, when); if (target != null) {
if (callback != null) {
proto.write(MessageProto.CALLBACK, callback.getClass().getName()); } else {
proto.write(MessageProto.WHAT, what); } if (arg1 != 0) {
proto.write(MessageProto.ARG1, arg1); } if (arg2 != 0) {
proto.write(MessageProto.ARG2, arg2); } if (obj != null) {
proto.write(MessageProto.OBJ, obj.toString()); } proto.write(MessageProto.TARGET, target.getClass().getName()); } else {
proto.write(MessageProto.BARRIER, arg1); } proto.end(messageToken); } //实现了Parcelable可序列化接口 public static final Parcelable.Creator
CREATOR = new Parcelable.Creator
() {
public Message createFromParcel(Parcel source) {
Message msg = Message.obtain(); msg.readFromParcel(source); return msg; } public Message[] newArray(int size) {
return new Message[size]; } }; public int describeContents() {
return 0; } public void writeToParcel(Parcel dest, int flags) {
if (callback != null) {
throw new RuntimeException( "Can't marshal callbacks across processes."); } dest.writeInt(what); dest.writeInt(arg1); dest.writeInt(arg2); if (obj != null) {
try {
Parcelable p = (Parcelable)obj; dest.writeInt(1); dest.writeParcelable(p, flags); } catch (ClassCastException e) {
throw new RuntimeException( "Can't marshal non-Parcelable objects across processes."); } } else {
dest.writeInt(0); } dest.writeLong(when); dest.writeBundle(data); Messenger.writeMessengerOrNullToParcel(replyTo, dest); dest.writeInt(sendingUid); } private void readFromParcel(Parcel source) {
what = source.readInt(); arg1 = source.readInt(); arg2 = source.readInt(); if (source.readInt() != 0) {
obj = source.readParcelable(getClass().getClassLoader()); } when = source.readLong(); data = source.readBundle(); replyTo = Messenger.readMessengerOrNullFromParcel(source); sendingUid = source.readInt(); }}

转载地址:http://qjqgn.baihongyu.com/

你可能感兴趣的文章
vim应用
查看>>
SOA性能管理现状
查看>>
Linux服务器常用命令
查看>>
Linux 检索
查看>>
防止机器注册
查看>>
git操作杂记
查看>>
thrift应用
查看>>
php 按元素值获取最佳元素组合
查看>>
支付服务集成-支付宝
查看>>
使用openssl生成RSA公钥和私钥对
查看>>
Linux常用命令
查看>>
Linux 定时任务应用
查看>>
什么是线程安全
查看>>
第三方支付集成
查看>>
MySQL server has gone away 问题的解决方法
查看>>
常用链接
查看>>
Easyui Pagenation应用方法
查看>>
MySQL十大优化技巧
查看>>
MySQL数据库管理常用命令
查看>>
php 文件操作
查看>>