handle作用:是满足线程与线程之间通信的

线程一旦被创建就会生成一个Looper对象,有且仅有一个



每个应用在运行的时候都会创建一个主线程(mainThread)。



主线程不能做耗时操作,子线程不能更新UI



Looper:一个线程可以产生一个Loop对象,由它来循环MessageQueue(消息队列)


handler:通过Handler对象和Looper进行沟通,以便发送消息到MessageQueue或者接收Looper从MessageQueue中读取的消息


MessageQueue:用来存放线程放入的消息


线程:UIThread通常就是mian thread,而Android启动程序的时候就会替它建立一个MessageQueue。




private Handler handler = new Handler() {
    //接收子线程中发送过来的消息
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 1:
                //通过obj的方式来获取方法
                text_tv.setText((String) msg.obj);
                break;
            case 2:
                //通过bundle的方法来获取数据
                text_tv.setText((String) msg.getData().getString("message"));
                break;
            case 3:
                //通过bundle的方法来获取数据
                text_tv.setText((String) msg.getData().getString("data"));
                break;

        }
    }
};





属于最原始的写法,但是其弊端是没有回收利用机制,如果一个APP中新建了很多消息而没有回收,那么会带来系统可卡顿,不利于系统的优化),通过what添加标识,通过obj添加内容存放数据( 当然我们也可以通过bundle来存放数据,都是可以的)。


new Thread() {
    @Override
    public void run() {
        //使用handler进行献策之间的消息通信
        Message message = new Message();
        //给message添加标识
        message.what = 1;
        //给message添加内容
        message.obj = "今天天气不错";
        //向消息队列中发送消息
        handler.sendMessage(message);
    }
}.start();



这种方式是最常用的,因为此方式创建的消息可以被回收利用,而且也很方便),也是通过what来添加标识,通过bundle来存放数据( 也是可以用obj来存放,都一样)。


new Thread() {
    @Override
    public void run() {
        //通过Message的obtain来创建消息,那么此消息可以被回收利用
        Message obtain = Message.obtain();
        obtain.what = 3;
        bundle.putString("data", "下雪了今天。");
        obtain.setData(bundle);
        handler.sendMessage(obtain);
    }
}.start();



用bundle存放数据和用obj存放数据的利弊:


bundle是一个键值对,可以定义成一个全局变量,进而多次使用,每次传不同的键名即可。而且bundle所传的的数据类型明确指明的有很多,传不同类型时很方便,和intent有点类似。


obj是一个万能的类型,可以传任何类型,但是拿的时候要强转,并且对于一些特殊类型不如bundle使用方便。当然,对于基本数据类型,还是obj来的方便一点。



new Thread(){
    @Override
    public void run() {
        Message msg =  new Message();
        //使用bundle来存放数据,可以放集合
        bundle.putString("message", "太阳出来了");
        msg.setData(bundle);
        msg.what = 2;
        handler.sendMessage(msg);

    }
}.start();



注:消息时不能抽成全局变量来使用,无论是使用new Message的方法还是通过Message.obtain的方法,都是只能此时创建此时用。