一.Handler是什么
Handler允许发送、处理消息和Runnuable。一个Handler只能绑定一个线程、一个线程只能绑定一个Looper
简言之,Handler就做了两件事:发送消息(或Runnuable)、处理消
息(或Runnable)。
第一件事:很好理解,体现在方法上就是:post,postDelayed,sendMessage,sendMessageDelay。
第二件事:第一件事发生后,Message入消息队列,按照时间先后进行排序。注意:消息队列,是优先级队列,排序方式是插入排序。这里,想一个问题,消息入队的时候,是如何保证线程安全的?既然队列中存在数据,Looper也开启了循环,那么每次循环,取出队列中的消息(第一个),进行回调处理。显而易见,这就是一个典型的“消费者-生产者”思想。
二.了解Handler的使用
1.Handler可以直接“new”吗?
主线程里是可以的,因为主线程里,已经创建了Looper。子线程,必须手动创建Looper,或者使用HandlerThread(内置Looper的线程),HandlerThread就不做解释了,主要核心就是如何创建Looper,并保证线程安全。
2.具体使用
这里的Handler,和主线程的Looper绑定,消息是从主线程发出的,回调也是主线程处理的。
public class MainActivity extends AppCompatActivity {
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 1:
Log.e("Tomato--->", "处理消息1");
break;
case 2:
Log.e("Tomato--->", "处理消息2");
break;
}
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Message message = Message.obtain();
message.what = 1;
handler.sendMessage(message);
Message message2 = Message.obtain();
message2.what = 2;
handler.sendMessage(message2);
}
}
这里的Handler,和子线程的Looper绑定,消息是从主线程发出的,回调是在子线程处理的。
public class MainActivity extends AppCompatActivity {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandlerThread handlerThread = new HandlerThread("thread-1");
handlerThread.start();
handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.e("Tomato--->", "thread-1处理消息1");
break;
case 2:
Log.e("Tomato--->", "thread-1处理消息2");
break;
}
}
};
Message message = Message.obtain();
message.what = 1;
handler.sendMessage(message);
Message message2 = Message.obtain();
message2.what = 2;
handler.sendMessage(message2);
}
}
3.主要看一下sendMessage做了些什么
senMessage之后,一步步调用,最终追到这个方法,如下:
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
//一方面,Message绑定了Handler;另一方面,target==null说明是一个异步消息,需要优先处理
//有关异步的消息发送,就不做解释,对于普通处理,没有帮助,而且,这个发送异步消息的方法,不对外暴露,就此作罢,有兴趣的,可以自行关注,尝试使用。
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
//设置为异步消息
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
3-1.target绑定之后做了什么
target是Message中的属性,其实就是Handler,那么消息入队之后,Message自然就和Handler进行了绑定。
创建Handler之后,发送消息,然后处理回调,来跟进一下回调的时机,进入Handler,找到方法,如下:
public void dispatchMessage(@NonNull M