Looper简析

参考http://blog.csdn.net/fesdgasdgasdg/article/details/52081773

  • 在异步线程中创建Handler(不带参数的构造方法)需要Looper.prepare( ),但是这个Handler是子线程的(可知Handler在哪个线程执行,就只是哪个线程的,并非所有的Handler都能执行UI操作,它只是一个辅助机制),如下,执行更新UI的操作会崩溃。
        new Thread(){
            @Override
            public void run() {
                super.run();
                Looper.prepare();
                Handler handler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        //子线程UI操作会导致闪退
                        et.setText("33");
                    }
                };
                Looper.loop();
                handler.sendEmptyMessage(0);
            }
        }.start();
  • 在创建Handler对象的过程中,回去获取当前线程的Looper对象,如果当前线程没有掉用过Looper.prepare() 将得到一个运行时错误:

        if (mLooper == null) {
            throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
        }
  • 当然也可以通过带参数(参数为主线程的Looper)的方式构造Handler,如下,此时这个Handler是运行在主线程的,可以直接更新UI

        new Thread(){
            @Override
            public void run() {
                super.run();
                Handler handler = new Handler(Looper.getMainLooper()){
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        et.setText("33");
                    }
                };
                handler.sendEmptyMessage(0);
            }
        }.start();
  • Activity中能直接创建Hnadler是因为已经在UI线程里面已经实例化了一个Looper,如下(Looper类准备一个主线程的Looper):

        /**
          * Initialize the current thread as a looper, marking it as an
          * application's main looper. The main looper for your application
          * is created by the Android environment, so you should never need
          * to call this function yourself.  See also: {@link #prepare()}
         */
        public static void prepareMainLooper() {
        prepare(false);
         synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
         }
        }

    上面这个方法的调用又是在ActivityThread(应用的主线程就是它)的main方法中,ActivityThread是在启动应用时系统创建的。而且Activity在attach方法中会传过来一个ActivityThread对象,并且使用这个ActivityThread对象赋予当前Activity的ActivityThread对象,至此,主线程的Looper就创建完成了,而这一切是由android系统完成的,我们不需要也不能手动创造主线程的Looper。

  • 一个handler实例可以用来发送和处理message,也可以与一个runnable对象关联.

  • 每一个handler只可以与一个looper关联,一个线程最多只能有一个looper,
  • 一个looper内置一个唯一的messageQueue。在同一个线程中,你可以再创建一个handler,与同一个looper和messageQueue关联。若多个handler关联同一个looper,则发送的message都会装载同一个messageQueue里面,由同一个looper管理。
  • looper抽取出message后,会让message找的妈妈。message是谁发送的,就有谁的handleMessage()方法处理。因为message.target = handler,message持有妈妈的电话号码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值