关闭

Looper简析

59人阅读 评论(0) 收藏 举报

参考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持有妈妈的电话号码
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6723次
    • 积分:407
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论