Handler、looper、message、messageQueue

Handler是做什么的?

handler是用来更新UI和发送,处理消息的。


Handler,Looper,messageQueue关系?

handler:发送消息
looper:接收消息,并发消息回传给hanlder自己
messageQueue:存储消息

常见的4种更新UI方法

...
  /更新Ui
        new Thread(){
            @Override
            public void run() {

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

//              4种更新UI的方法全部都是子UI线程(主线程进行)
//              handler1();
//              handler2();
//              handler3();
//              handler4();

            }
        }.start();;
    }


    private void handler1() {
        //实际上在内部也是调用handler.sendMessageDelayed(),也是发送message
        handler.post(new Runnable() {

            @Override
            public void run() {
                bt1.setText("change bt1");
            }
        });
    }

    private void handler2() {
        //实际上发送信息给hanler, 然后在handleMessage方法里更新UI
        handler.sendEmptyMessage(1);
    }

    private void handler3() {
        //实际上内部是调用handler.post()
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                bt1.setText("change bt1");
            }
        });
    }

    private void handler4() {
        //实际上内部是调用handler.post()
        bt1.post(new Runnable() {

            @Override
            public void run() {
                bt1.setText("change bt1");
            }
        });
    }
    ...

主线程与子线程传递消息,信息交互

实际上是主线程的handler与子线程的handler互相发送消息

public class MainActivity extends Activity{

    private Button bt1;
    private Button bt2;

    //这里的执行操作在主线程
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            threadHandler.sendEmptyMessageDelayed(1, 1000);
            Log.v("TAG", "handler-->"+Thread.currentThread());
        };
    };
    private Handler threadHandler;

    private HandlerThread thread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        thread = new HandlerThread("handlerThread");
        thread.start();

        //这里的执行操作在子线程
        threadHandler = new Handler(thread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                handler.sendEmptyMessageDelayed(333, 1000);
                Log.v("TAG", "threadHandler-->"+Thread.currentThread());
            }
        };

        bt1 = (Button) findViewById(R.id.button1);
        bt1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                handler.sendEmptyMessage(1);

            }
        });
        bt2 = (Button) findViewById(R.id.button2);
        bt2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                handler.removeMessages(333);//remove的what 要对应
            }
        });
        }

效果
这里写图片描述

注意要点:

1.子线程中的hanlder必须指定一个looper,looper从该子线程获得
2.实际上停止消息的传递,要在刚发生的一瞬间,remove掉该message(猜测:刚发生后,还没在Queue里取出message,然后remove调,就不会执行handleMessaage,从而停止通信)


实际上是可以在子线程更新UI,当强烈不推荐这样,推荐在hanlder内更新UI

子线程更新UI :

 new Thread(){
            @Override
            public void run() {
                bt1.setText("change bt1");

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        }.start();;
    }

实际上就是在调用Thread.sleep()之前setText(),这样可以更新UI且不报错. 若是在Thread.sleep()之后setText()就会报异常,再重复一次,不推荐在子线程更新UI
//这些问题与ViewRootIMP有关

转载于:http://www.imooc.com/learn/267


2016/4/8更新

1.looper.prepare()获得一个当前线程里的looper实例,在实例里创建一个messageQueue
2.looper.loop()不断从messageQueue里取得message并回调msg.target.dispatchMessage(msg)
3.在handler构造方法里得到当前线程的looper实例,并与looper实例里面的messagequeue相关联
4.Handler的sentMessage方法会把message的taget赋值给handler,然后加入到messageQueue里
5.在构造handler时会重写handlermessage方法,实际上就是msg.target.dispatchMessage(msg)最终调用的方法

转载于:http://blog.csdn.net/lmj623565791/article/details/38377229/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值