1.Handler-控制器
2.Looper-轮询
3.Message-消息对象
4.MessageQueue-单链表结构的消息队列
一般情形下,涉及到异步的操作才需要引入handler来接收异步操作的结果,来更新UI信息.所以常规操作是这样
图片引用自
https://zhuanlan.zhihu.com/p/25222485
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText("对UI进行操作");
}
};
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.mytv);
new Thread(new Runnable() {
@Override
public void run() {
//模拟耗时操作
SystemClock.sleep(3000);
handler.sendMessage(new Message());
}
}).start();
}
首先创建一个handler
第二创建一个Thread
Thread处理完某项操作以后,通过handler.sendMessage(msg)把异步的结果发送到消息队列MessageQueue中,
然后我们通过复写handlerMessage()完成该次操作.
Looper呢?MessageQueue呢?
这TM到底怎么关联起来的.
图同样取自https://zhuanlan.zhihu.com/p/25222485
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
获取MessageQueue 判断是否为空,不为空
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
重头戏
boolean enqueueMessage(Message 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.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
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; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
Message类中几个有趣的东西
Handler target;
Message next;
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
重点标注target,你会发现尼玛:Message在创建的时候就关联了handler.
关于Looper
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
重点注意ThreadLocal,
这是个什么类呢?
static final ThreadLocal
ThreadLocal用于保存某个线程变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
1、ThreadLocal.get: 获取ThreadLocal中当前线程变量的值。
2、ThreadLocal.set: 设置ThreadLocal中当前线程变量的值。
3、ThreadLocal.remove: 移除ThreadLocal中当前线程变量的值。
4、ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值。
这个太重要了.这是个啥子勒.
ThreadLocal保存保存了各自线程的Looper,Looper又包含MessageQueue,Looper的构造器
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
sendMsg发送一次,ThreadLocal就set一次.
Looper中loop方法是个死循环(在主线程的死循环为啥没引起ANR呢?)
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
//......
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
//......
msg.recycleUnchecked();
}
呀哈,谁污染,谁治理,谁发送,谁处理
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
结束:handler收到了消息,最后过上了没羞没糙的生活