一、Handler的创建
Handler的创建会关联一个Looper
对象,而Looper
对象关联着MessageQueen
对象,所以在Handler创建时,取出Looper
和MessageQueen
public Handler(Callback callback, boolean async) {
...
//取出Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//取出Looper中的MessageQueen
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
Looper
是存放在ThreadLocal
里面的,可以看下面的源码
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
整个创建的过程就完了,这里做了哪几件事:
- 取出
Looper
- 取出
Looper
中的MessageQueen
二、Handler发送消息
1、方式一:sendMessage(Message msg)
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
//往下追踪
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
//往下追踪
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
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);
}
//调用sendMessage方法其实最后是调用了enqueueMessage方法
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//为msg.target赋值为this,也就是把当前的handler作为msg的target属性
//如果大家还记得Looper的loop()方法会取出每个msg然后执行msg.target.dispatchMessage(msg)去处理消息,其实就是派发给相应的Handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//最终调用queue的enqueueMessage的方法,也就是说handler发出的消息,最终会保存到消息队列中去
return queue.enqueueMessage(msg, uptimeMillis);
}
2、方式二:post(Ruunable r)
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
其实post()方法最终也会保存到消息队列中去,和上面不同的是它传进来的一个Runnable
对象,执行了getPostMessage
()方法,我们往下追踪
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
实质上就是将这个Runnable
保存在Message的变量中,这就导致了我们下面处理消息的时候有两种不同方案
三、Handler处理消息
你还记得前面所说Looper
中msg.target.dispatchMessage()方法吗?这个方法就是调用Handler
的dispatchMessage()
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//1. post()方法的处理方法
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//2. sendMessage()方法的处理方法
handleMessage(msg);
}
}
//1. post()方法的最终处理方法
private static void handleCallback(Message message) {
message.callback.run();
}
//2. sendMessage()方法的最终处理方法
public void handleMessage(Message msg) {
}
整个处理的过程就完了,这里做了哪几件事:
- post()方法的处理方法就是将传进来的
Runnable
执行run()方法 sendMessage
()方法的处理方法就是执行handleMessage
()空方法,这也是我们为什么要在Handler重写这个方法的原因
三、Handler 的post(Runnable)和handleMesaage的用法
1).post(Runnable)用法:
package mountain_hua.learn_handler1;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
//先在主线程中创建Handler,Handler会自动与主线程绑定
private Handler handler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("main thread id " + Thread.currentThread().getId());
test_handmessage();
}
public void test_handmessage(){
new Thread(){
@Override
public void run(){
//处理信息
try{
//模拟费时操作
System.out.println("run thread id " + Thread.currentThread().getId());
sleep(1000);
//这里使用Runnable
Runnable runnable=new Runnable() {
@Override
public void run() {
System.out.println("Runnable thread id " + Thread.currentThread().getId());
}
};
//这里执行post(Runnable)操作
handler.post(runnable);
}catch (Exception e){
e.printStackTrace();
}
}
}.start();
}
}
首先在主线程中创建了一个handler,这时handler会自动绑定主线程,然后在一个新线程里面创建了Runnable对象,并且用了handler的post(Runnable)操作来发送消息给在主线程中的handler执行。我们看看打印出来的结果:
07-30 21:34:23.891 21509-21509/mountain_hua.learn_handler1 I/System.out: main thread id 1
07-30 21:34:23.893 21509-21560/mountain_hua.learn_handler1 I/System.out: run thread id 9378
07-30 21:34:24.894 21509-21509/mountain_hua.learn_handler1 I/System.out: Runnable thread id 1
结果可以看到Runnable与main线程id相同,说明了Runnable里面执行的事件是被handler放在主线程中执行的,与Run所在线程无关 。
2).handleMessage用法:
package mountain_hua.learn_handler1;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
test_handmessage();
test_handmessage1();
}
public void test_handmessage(){
new Thread(){
@Override
public void run(){
//处理信息
try{
//模拟费时操作
System.out.println("run thread id " + Thread.currentThread().getId());
sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
Message msg=new Message();
// 也可以用下面两种方法获得Message
// Message msg1=Message.obtain();
// Message msg2=handler.obtainMessage();
msg.what=0;//msg.what的类型是int型,作为msg的识别码
msg.arg1=1;//msg.arg1的类型是int型,可以传递简单的参数
msg.arg2=2;//msg.arg2的类型是int型,可以传递简单的参数
msg.obj="Object类型";//msg.obj是Object型,可以传递任意参数
//将Message发送给handler
handler.sendMessage(msg);
}
}.start();
}
public void test_handmessage1(){
new Thread(){
@Override
public void run(){
//处理信息
try{
//模拟费时操作
System.out.println("run thread id " + Thread.currentThread().getId());
sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
Message msg=new Message();
// 也可以用下面两种方法获得Message
// Message msg1=Message.obtain();
// Message msg2=handler.obtainMessage();
msg.what=99;//msg.what的类型是int型,作为msg的识别码
msg.arg1=100;//msg.arg1的类型是int型,可以传递简单的参数
msg.arg2=101;//msg.arg2的类型是int型,可以传递简单的参数
msg.obj="Object类型";//msg.obj是Object型,可以传递任意参数
//将Message发送给handler
handler.sendMessage(msg);
}
}.start();
}
Handler handler=new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
System.out.println("handleMessage thread id " + Thread.currentThread().getId());
System.out.println("msg.arg1:" + msg.arg1);
System.out.println("msg.arg2:" + msg.arg2);
break;
case 99:
System.out.println("handleMessage thread id " + Thread.currentThread().getId());
System.out.println("msg.arg1:" + msg.arg1);
System.out.println("msg.arg2:" + msg.arg2);
}
}
};
}
这里用两个Messge给主线程中的Handler发送消息,打印出的信息为:
07-30 21:19:08.532 2461-2782/mountain_hua.learn_handler1 I/System.out: run thread id 9311
07-30 21:19:08.532 2461-2783/mountain_hua.learn_handler1 I/System.out: run thread id 9312
07-30 21:19:09.532 2461-2461/mountain_hua.learn_handler1 I/System.out: handleMessage thread id 1
07-30 21:19:09.532 2461-2461/mountain_hua.learn_handler1 I/System.out: msg.arg1:1
07-30 21:19:09.532 2461-2461/mountain_hua.learn_handler1 I/System.out: msg.arg2:2
07-30 21:19:10.532 2461-2461/mountain_hua.learn_handler1 I/System.out: handleMessage thread id 1
07-30 21:19:10.532 2461-2461/mountain_hua.learn_handler1 I/System.out: msg.arg1:100
07-30 21:19:10.532 2461-2461/mountain_hua.learn_handler1 I/System.out: msg.arg2:101
可以看到handler处理消息队列是在主线程中处理的(handler在哪个线程中创建的就与哪个线程绑定), 与run存在的线程无关。