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

网站类别标签文本网站开发与设计

网站类别标签文本,网站开发与设计,常熟做网站多少钱按,wordpress媒体库插入图片不显示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.hkea.cn/news/681122/

相关文章:

  • wordpress块引用一个网站可以优化多少关键词
  • 360网站卖东西怎么做的无锡seo优化公司
  • 邢台人民网站百度视频推广怎么收费
  • 常州天启建设公司网站高端快速建站
  • ppt模板免费下载网站不用登录seo测试工具
  • 四川建设人才网官网查询阜新网站seo
  • 太原网站开发定制百度网盘官网下载
  • 业主装修日记那个网站做的好片多多可以免费看电视剧吗
  • 租车网站建设站长之家源码
  • 昌吉州回族自治州建设局网站地产渠道12种拓客方式
  • 北京市网站公司网络项目免费的资源网
  • 电子商务网站规划、电子商务网站建设站长工具 忘忧草
  • 凡科建网关键词优化公司哪家好
  • seo排名推广工具seo公司多少钱
  • 做视频网站赚钱怎么在百度上推广自己的公司信息
  • 网站建设凡科厦门网站建设平台
  • 互联网行业pest分析福州百度快速优化排名
  • 做网站的接私活犯法吗如何对网站进行推广
  • 身高差效果图网站优化师和运营区别
  • 谷歌wordpress建站搜索引擎算法
  • .net 购物网站开发源代码发布信息的免费平台
  • 自己做一网站大学生网络营销策划书
  • 关于网站建设的文章百度域名收录提交入口
  • 国人在线做网站推广图片大全
  • 郑州网站建设七彩科技四年级说新闻2023
  • 在什么网站上做自媒体seo整站怎么优化
  • 网站开发要注意安全性公司优化是什么意思
  • 河北邢台做移动网站开通网站需要多少钱
  • 天河网站建设多少钱淘宝关键词优化
  • 中型网站 收益关键词排名查询官网