Handler就是一个用来接收非UI线程信息来更新UI的一个函数。一般和多线程一起使用,最多的是Runnable接口
Handle的原理是什么?
一,Handle封装了消息的发送(主要是包括消息发送给谁)
1,Looper内部包含一个消息队列也就是MessageQueue,所有Handle发送的消息都走向这个消息队列
2,Looper.Looper方法,就是一个死循环,不断的从MessageQueue取消息,如果有消息就处理消息,若没有消息就阻塞
二,MessageQueue,就是一个消息队列,可以添加消息也可以处理消息。
三,Handle也很简单,内部会跟Looper进行关联,也就是说在Handle的内部可以找到Looper,找到了Looper也就是找到了MessageQueue,也就是说在Handle方法里面发送消息其实就是向MassageQueue消息队列里面发送消息
总结:Handle负责发送消息,Looper负责接收Handle发送的消息,并直接把消息回传给Handle自己,而MessageQueue就是一个储存消息的容器
代码以及解析如下:
class Man{
//新建一个内部类,包含两个属性
public int age;
public String name;
//重写toString方法
public String toString() {
return "姓名:"+name+"年龄:"+age;
}}
public class MainActivity extends Activity {
//定义两个TextView
TextView textView,textView2;
Handler handler =new Handler()
{
//在handle重写handleMessage方法
public void handleMessage(Message msg) {
//通过settext方法实现UI交互
textView.setText(""+msg.arg1);
textView2.setText(""+msg.obj);
};
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//关联ID
textView=(TextView)findViewById(R.id.Textview);
textView2 =(TextView)findViewById(R.id.textView1);
new Thread(){
//新建一个子线程
public void run() {
try {
//是线程休眠一秒
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message message =new Message();
//new 一个message对象
message.arg1=88;
Man man =new Man();
man.age=18;
man.name="zza";
message.obj=man;
//分别向msg传输一个int类型的变量,和一个object类型的值
handler.sendMessage(message);
};
}.start();//调用start方法
}
另外还学习了关闭当前UI更新的方法:
handler.removeCallbacks(myRunnable);//停止当前的UI更新
还有截获handleMessage方法,就是handle里面自带的一个方法叫做callback方法,会自动生成一个带有布尔返回值的handleMessage方法,若返回值为false则继续运行不含有返回值的handleMessage方法,反之则不会运行。关键代码如下:
Handler handler =new Handler(new Callback() {
//callback带有一个Boolean返回值的hanMessage方法,可用作截获handleMessage方法
//若返回值为false则继续运行不含有
//返回值的handleMessage方法,反之则不会运行
@Override
public boolean handleMessage(Message arg0) {
Toast.makeText(getApplicationContext(), ""+12, 2000).show();
return false;
}
}){
public void handleMessage(Message arg0) {
Toast.makeText(getApplicationContext(), ""+122, 1000).show();
}};
///
handler.sendEmptyMessage(1);//发送一个空值
问题:Android为什么要设计只能通过Handle机制更新UI呢?
答:最根本的问题是解决多线程并发的问题,假设如果在一个activity里面,有多个多线程去更新Ui,并且都没有加锁机制,那么就会造成更新界面混乱,那如果更新UI的操作都进行加锁处理会使性能下降。处于对以上的问题的考虑Android给我们提供了一套更新UI的机制,我们只需要遵循这样的机制就可以了,根本不用去关心多线程的问题,所有的更新UI的操作都是在主线程的消息队列当中轮训处理的。
自己创建一个Handle方法,具体方法如下:
private Handler handler =new Handler()
{
//在外部新建一个Handle对象
public void handleMessage(android.os.Message msg) {
//调用handleMessage方法
};
};
//新建一个内部类,使其继承于Thread
class Mythread extends Thread{
public void run(){
//重写内部的run方法
//调用Looper的prepare方法来给线程创建一个消息循环
Looper.prepare();
handler =new Handler(){
public void handleMessage(android.os.Message msg) {
//再次调用handleMessage方法,并在Logcat里面打印当前线程的名称
System.out.println("currentThread"+Thread.currentThread());
};
};
Looper.loop();//Looper.loop方法来一直重复读取消息
}
}
private Mythread mythread =new Mythread();//创建一个Mythread对象
@Override
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
//发送一个空值
handler.sendEmptyMessage(1);