ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

什么是Handler的同步屏障机制?,android适配器模式

2022-01-27 18:04:34  阅读:206  来源: 互联网

标签:异步 屏障 适配器 next Handler 消息 msg android target


正常插入消息会调用enqueueMessage方法,同时将handler赋值给message的target。

//将消息插入消息队列

private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,

long uptimeMillis) {

msg.target = this;

msg.workSourceUid = ThreadLocalWorkSource.getUid();

//进行判断是否将消息设置为异步消息

if (mAsynchronous) {

msg.setAsynchronous(true);

}

return queue.enqueueMessage(msg, uptimeMillis);

}

在MessageQueue中进行判断,如果target为空也就是这个message没有对应的handler则会报异常。

boolean enqueueMessage(Messag
e 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.");

}

// 如果需要唤醒,则唤醒

if (needWake) {

nativeWake(mPtr);

}

通过MessageQueue的postSyncBarrier方法插入屏障,message的target属性为null

private int postSyncBarrier(long when) {

synchronized (this) {

final int token = mNextBarrierToken++;

//msg没有为target属性赋值

final Message msg = Message.obtain();

//根据时间插入到MessageQueue中

if (when != 0) {

while (p != null && p.when <= when) {

prev = p;

p = p.next;

}

}

if (prev != null) { // invariant: p == prev.next

msg.next = p;

prev.next = msg;

} else {

msg.next = p;

mMessages = msg;

}

//返回一个序号,通过它可以对屏障消息进行撤销

return token;

}

}

经过以上的操作,我们可以总结出

  • 屏障消息和普通消息的区别是屏障消息没有target属性,普通消息有target属性是因为要将消息分发给target指向的handler处理

  • 屏障消息会插入到MessageQueue中合适的位置,这个消息以后的普通消息将被屏蔽

  • postSyncBarrier返回一个int类型的数值,通过这个数值可以撤销屏障

  • postSyncBarrier方法是私有的,如果我们想调用它就得使用反射

  • 插入普通消息会唤醒消息队列,但是插入屏障不会

如何发送异步消息

通常我们发送的都是普通消息,如果想发送异步消息

  • 可以在创建handler时使用如下的构造器中的一种,同时将async参数设置为true,这样这个handler发送的消息就都是异步消息了。

public Handler(boolean async) {

this(null, async);

}

public Handler(@NonNull Looper looper, @Nullable Callback callback) {

this(looper, callback, false);

}

public Handler(@Nullable Callback callback, boolean async) {

mLooper = Looper.myLooper();

if (mLooper == null) {

throw new RuntimeException(

"Can’t create handler inside thread " + Thread.currentThread()

  • " that has not called Looper.prepare()");

}

mQueue = mLooper.mQueue;

mCallback = callback;

mAsynchronous = async;

}

  • 除了这种方式还可以直接设置消息的类型为异步消息

public void setAsynchronous(boolean async) {

if (async) {

flags |= FLAG_ASYNCHRONOUS;

} else {

flags &= ~FLAG_ASYNCHRONOUS;

}

}

消息处理的过程

MessageQueue是通过next方法来遍历消息的

@UnsupportedAppUsage

Message next() {

for (;

标签:异步,屏障,适配器,next,Handler,消息,msg,android,target
来源: https://blog.csdn.net/m0_66264856/article/details/122721562

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有