网站服务器连接被重置外贸推广平台有哪几个
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()系列方法