一、Handler概述
(1)、handler是android给我们用来提供用来更新UI的一套机制、也是一套消息处理机制
(2)、为什么用handler 不用它会抛出异常
最根本目的是解决多线程并发的问题
当有多个线程更新UI,且没有加锁机制,会发生界面错乱;若对所有更新UI的操作都加锁,则性能会下降
二、Handler使用方法
(1 ) post(Runnable)
Handler不断postDelayed一个runnable象,制定严格1s执行(其实post发出的Runnable对象最后都被封装成message)
public class MainActivity extends AppCompatActivity {
private TextView textView;
private ImageView imageView;
private Handler handler = new Handler();
private int images[] = {R.drawable.a,R.drawable.b,R.drawable.c};
private int index;
private MyRunable myRunable = new MyRunable();
class MyRunable implements Runnable{
@Override
public void run() {
index ++;
index = index%3;
imageView.setImageResource(images[index]);
handler.postDelayed(myRunable,1000);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview);
imageView = (ImageView) findViewById(R.id.imageView);
handler.postDelayed(myRunable,1000);//在主线中调用
}
}
(2)sendMessage
1)传递对象
public class MainActivity extends AppCompatActivity {
private TextView textView;
private ImageView imageView;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg){
textView.setText(""+msg.obj);
}
};
private int images[] = {R.drawable.a,R.drawable.b,R.drawable.c};
private int index;
private MyRunable myRunable = new MyRunable();
class Person{
public int age;
public String name;
@Override
public String toString() {
return "name=" + name + " age=" +age;
}
}
class MyRunable implements Runnable{
@Override
public void run() {
index ++;
index = index%3;
imageView.setImageResource(images[index]);
handler.postDelayed(myRunable,1000);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview);
imageView = (ImageView) findViewById(R.id.imageView);
new Thread() {
public void run() {
try {
Thread.sleep(2000);
// Message message = new Message();
// message.arg1 = 88;
// message.arg2 = 100;
Message message = handler.obtainMessage();//返回一个message对象,也可用上面的方法
Person person = new Person();
person.age = 23;
person.name = "Chartherine";
message.obj = person;
message.sendToTarget();//也可用下面的方法
// handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();//写thread方法时一定要调用start方法,否则run方法无法执行
}
}
2) 利用Handler将消息移除
public void onClick(View v) {
handler.removeCallbacks(runable);
}
3)在handler发送消息的时候,我们可以截获该消息
(runnable对象:new callback)
private Handler handler = new Handler(new Handler.Callback(){
public boolean handleMessage(Message msg) {
Toast.makeText(getApplicationContext(), "" + 1, Toast.LENGTH_LONG).show();
return false;/*true 说明handler发送来的消息已经截获(消息完全符合拦截的对象),则handleMessage方法不会执行,即点击事件无响应*/
}
})
{
public void handleMessage( Message msg){
Toast.makeText(getApplicationContext(),""+2,Toast.LENGTH_LONG).show();
}
};
三、Handler的原理
(1) Handler封装了消息的发送(包括消息发送给谁)
handler和Looper以及MesageQueue的差别
1) Handler,内部会跟Looper进行关联(sendMessage操作:发出请求;handMessage:自己操作的过程)
(在Handler的内部可以找到Looper,找到L也就能找到M,所以在Handler中发送消息,就是想M队列中发送消息)
2) Looper
1.内部包含一个消息队列也就是MessageQueue,可将handler发送的消息进行插入或者移除
2.Looper.Looper方法(应答的过程;消息回传),就是一个死循环,不断轮询MessageQueue中的消息,有就处理,无就堵塞
3)MessageQueue,是一个消息队列,可以增加消息,并处理消息
总结:1.Handler负责发送消息、Looper负责接收Handler发的信息,并把信息回传给Handler,MessageQueue就是一个存储消息的容器
2.一个线程可以有多个Handler,但只能有一个Looper
3.Handler的用处:1)可以在任意线程发送消息,且会被添加到关联的MQ上
2)Handler在其关联的looper线程中处理消息(解决了android不能在其他非主线程更新UI的问题)
3)android的主线程也是一个Looper线程