在上篇 Handler 原理分析和使用(一)中,介绍了一个使用Handler的一个简单而又常见的例子,这里还有一个例子,当然和上一篇的例子截然不同,也是比较常见的,实例如下。

 import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private TextView myTextView;
private Button myButton;
private Handler myHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myHandler = new Handler();
myTextView = (TextView)this.findViewById(R.id.text_view);
myButton = (Button)this.findViewById(R.id.post);
myButton.setOnClickListener(this);
} @Override
public void onClick(View view) {
int id = view.getId();
if(id == R.id.post){
Runnable updateUI = new Runnable() {
@Override
public void run() {
myTextView.setText("I get Post Message");
}
};
//将该线程发送到主线程运行
myHandler.post(updateUI);
}
}
}

实际运行这个例子,点击Button之后,TextView文字内容会变成“I get Post Message”。为什么会是这样,我们从源码开始着手查看。

先看Handler的post(Runnable)方法(post还有几个姊妹方法,这里不再一一论述,都是殊途同归)。源码如下:

 public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}

调用了sendMessageDelayed(...), 先看getPostMessage(r),源码如下:

 private static Message getPostMessage(Runnable r) {
//获取消息池中的一个消息
Message m = Message.obtain();
//将Runnable作为消息的callback
m.callback = r;
return m;
}

在看sendMessageDelayed(Message,int)的源码:(在Handler 原理分析和使用(一)中有说明)

 public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//绑定Handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//将Message推入MessageQueue
return queue.enqueueMessage(msg, uptimeMillis);
}

实际上和sendMessage(Message)一样的流程。当然了紧接着Looper.loop()。然后调用到dispatchMessage(Message) 该方法需要在此重新说明。看源码:

 public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//如果message的callback不为空,则
handleCallback(msg);
} else { if (mCallback != null) {
//如果Handler的callback不为空,则
if (mCallback.handleMessage(msg)) {
return;
}
}
//处理Message
handleMessage(msg);
}
}

在进入handleCallback(Message)方法查看源码:

 private static void handleCallback(Message message) {
//直接执行run方法
message.callback.run();
}

注意,此时message已经是主线程对象。因此调用run方法就是在主线程中运行。

此外还需要注意,runnable要处理的内容会在主线程中处理,因此不能够占用太多的时间,从而造成ANR。

--------------------------------------------------------------------------------------------

之所以用一条线隔开,是因为还有一个实例需要说明。请注意dispatchMessage(message)里面的这段代码:

 if (mCallback != null) {
//如果Handler的callback不为空,则
if (mCallback.handleMessage(msg)) {
return;
}
}

这个mCallback是从哪里来,这个有引出Handler的另一个使用方法。

首先来看Handler的初始化方法,有一下几个:

1. publicHandler()

2. publicHandler(Callback)

3. publicHandler(Looper)

4. publicHandler(Looper, Callback)

第1,3个一眼看去就明白。第4个只要明白第2个也就通了。

关键点,Callback是什么?是一个接口。源码如下:

 public interface Callback {
public boolean handleMessage(Message msg);
}

该接口实际上是要求实现handleMessage(Message)方法,相信这个方法大家都不陌生。

再看该初始化方法:

 Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});

这里已经很明显了。就是重新定义了handleMessage方法。那么在dispatchMessage方法中如果发现mCallback不为空,则所有的消息都执行该Callback定义的handleMessage(Message).

具体的例子不想写了。今天就到这里吧。太累了。明天不在深入,而是扩展。