当前位置: 首页 > news >正文

宁波市镇海建设交通局网站首页潍坊网站定制公司

宁波市镇海建设交通局网站首页,潍坊网站定制公司,网站建设维护有哪些内容,山西运城网站建设1.消息循环机制 Handler是Android提供的用于发送、接收和处理Message或Runnable对象的类,它与Message、MessageQueue、Looper类以及当前线程实现了一个消息循环机制,用于实现消息的异步加载和处理。 整个异步消息处理流程简易图: ①Message:消息体,用于装载需要发送的对…

1.消息循环机制
Handler是Android提供的用于发送、接收和处理Message或Runnable对象的类,它与Message、MessageQueue、Looper类以及当前线程实现了一个消息循环机制,用于实现消息的异步加载和处理。

整个异步消息处理流程简易图:
在这里插入图片描述
①Message:消息体,用于装载需要发送的对象。
一般使用Message.obtain()或Handler.obtainMessage()获取Message实例对象,而不直接使用new Message()。Message.obtain()会从消息池中获取一个Message对象,如果消息池中是空的才会new一个新Message,这样有利于消息资源的利用。
②Handler:直接继承自Object,一般是在子线程中发送Message或Runnable对象到消息队列中;然后在主线程中接收并处理从消息队列分发出来的Message对象。
③MessageQueue:消息队列,内部使用的是单链表结构(插入和删除效率比较高)。它由对应的Looper对象创建,并由Looper对象管理。
每个线程只会有一个消息队列。
④Looper:不断从消息队列中取出消息进行分发。调用Looper.loop()方法后,就会进入到一个无限循环中,每当发现消息队列中存在一条消息,就将它取出并调用Handler的handleMessage()方法处理消息。
每个线程只会有一个Looper对象。

下面按照消息循环处理机制的步骤分别解析。

2.第一步:准备好要发送的消息Message
Message类内部维护了一个Message对象池用于Message对象的复用,使用obtain()可以直接从对象池中获取Message对象,避免重新创建。
public final class Message implements Parcelable {
//Message对象的几个重要参数
public int what;
public int arg1;
public int arg2;
public Object obj;
public long when;
Handler target;
Runnable callback;
Message next;

public static final Object sPoolSync = new Object();
private static Message sPool; //对象池
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flag = 0; //clear in-use flag
sPoolSize --;
return m;
}
}
//若池内无消息,则还是用new创建
return new Message();
}
}
如果消息池内有消息,则返回第一个消息实例,否则新建消息对象。
所以一般使用obtain()获取Message对象,避免每次都使用new重新分配内存,消耗更多的内存资源。

Message类中其他带参数的obtain()重载方法,都是先使用obtain()得到对象实例后再进行赋值操作。注意obtain( Handler h, Runnable callback)这个静态方法,因为涉及到Message的两个重要成员变量:
public final class Message implements Parcelable {
Handler target;
Runnable callback;
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;
return m;
}
}
同样是赋值操作,其中target指向Message所关联的Handler。除了target还有一个callback,这个callback也是配合着Handler来发挥作用的。

总结Message:
①通常使用Message.obtain()方法获取Message对象实例;
②Message有两个重要的成员变量,分别为target 和callback,一个是Handler类型,一个是Runnable类型;
③Message有4个公开变量what、arg1、arg2、obj,可以存储消息进行传递;
④Message的对象池是一个链表,所以还有一个next成员变量,也是Message类型。

3.第二步:创建Handler对象
Handler在消息传递过程中扮演着重要的角色,是消息的主要处理者。Handler的主要作用就是发送、接收并处理消息。
Handler的构造方法:
Handler()
Handler(Callback callback)
Handler(boolean async)
Handler(Callback callback, boolean async)
Handler(Looper looper)
Handler(Looper looper, Callback callback)
Handler(Looper looper, Callback callback, boolean async)
这些构造方法都是相继往下调用的,所以直接看最后一个方法:
public class Handler {
final Looper mLooper;
final MessageQueue mQueue;
final Callback mCallBack;
final boolean mAsynchronous;
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
}
Handler的这些构造方法里,如果looper不传值则会使用Looper.mylooper()获取当前线程的Looper实例;如果传值则使用传进来的looper对象。一般在子线程中使用Handler时才传此参数。

再看另外一个构造方法:
public class Handler {
public Handler(Callback callback,boolean async){
mLooper = Looper.myLooper(); //参数中没有传Looper,则使用当前线程的Looper对象
if (mLooper == null) {
throw new RuntimeException(“Can’t create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()”);
}
mQueue = mLooper.mQueue; //mQueue为Looper对象对应的消息队列
mCallback = callback; //接口回调
mAsynchronous = async; //是否为异步消息
}

public interface Callback {
public boolean handleMessage(Message msg);
}
}
首先获取Handler实例所在线程的Looper对象。如果Looper不为空就获取Looper对应的消息队列,赋值给Handler的成员变量mQueue,然后设置Callback用于处理消息回调。

在一个线程中可以创建多个handler对象,这些handler都往这个线程的Looper中塞消息,Looper按照顺序去轮询到消息,进行处理。
比如在线程A中,可以使用线程B的handler发送消息,这个消息会发送到到线程B的消息队列中,线程B的handler通过其Looper在线程B中轮询消息。这个handler就像是线程B放出去的口子,谁向线程B发消息,就通过我来塞。

在子线程中声明的Handler是不能直接更新UI的,需要调用Handler相关的构造方法,传入主线程的Looper,这样创建的Handler实例才能进行UI的更新操作。

注意,子线程默认是没有开启Looper的,所以在子线程中创建Handler之前,必须先通过Looper.prepare()方法开启子线程的Looper,否则就会报异常:
if (mLooper == null) {
throw new RuntimeException(“Can’t create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()”);
}
创建了Handler对象,接下来就可以用Handler的sendMessage()方法来传递对象了。

总结Handler:
(1)Handler有且只能绑定一个线程的Looper;
(2)Handler把消息发送给Looper对应的消息队列MessageQueue中,然后等待处理。

Handler创建完成后,它负责把Message发送到消息队列mQueue,然后排队等待,Looper从消息队列将消息一个一个的取出来,然后通知消息对应的Handler去分发处理消息。

4.第三步:handler发送Message
第一步、第二步创建好了handler和Message对象,接下来就需要使用创建好的handler对象来发送该Message对象了。

Handler发送消息有两种方法:sendMessage()和postMessage()。

①首先看sendMessage()系列方法

http://www.yayakq.cn/news/21141/

相关文章:

  • 网站搭建设计wap网站前景
  • 做网站都需要哪些费用现在广告行业好做吗
  • 网站制作明细清单海城网站建设
  • 青海网站建设公司电话公司宣传册模板
  • 热点 做网站和营销 我只服他个人简约网站模板
  • 自己做报名网站为什么做可信网站
  • 网站开发的语言效果图怎么收费
  • 梅州市做试块网站wordpress widget 模板
  • 潍坊网站排名优化深圳公关公司推荐乐云seo
  • 路桥网站建设是怎么回事儿
  • 如何判断一个网站的价值一般卖机械行业的做哪些网站
  • 网站开发需要的资料上海纽约大学官网 wordpress
  • 百度推广还要求做网站商城网站系
  • 网站建设与维护 课件比较有特色的网站
  • 设计手机网站公司百度一下电脑版首页网址
  • 电商模板网站免费商梦建站
  • 中国营销传播网app做推广优化的网站有哪些
  • 上海网站建设开发网站的要求
  • 网站快速注册风科网免费网站
  • 东莞知名网站建设网络设备维护是做什么的
  • 网站改版设计方案做视频网站怎么挣钱吗
  • 电子商务网站建设与设计宁阳网站定制
  • 网站用什么语言好江都建设总部网站
  • 怎样做网站建设方案wordpress启用主题网站出错
  • 1m带宽可以建设电商网站吗做生存曲线网站
  • 重庆建设工程公司网站html5手机网站开发经验
  • 做口腔科网站网站开发运行环境论文
  • 怎么进电力建设公司网站做棋牌网站违法嘛
  • 网站前台登录模板公众号 创意名字
  • 青岛金桥建设机械有限公司网站做运动鞋评价的网站