handler

Handler机制:用于在工作线程与UI线程之间进行消息传递的机制。(因为工作线程不能直接操作UI组件的属性值)

  1. Handler的作用:
    1) 在新启动的线程(非UI线程)中发送消息。
    2) 在主线程(UI线程)中获取消息、处理并完成UI组件的操作。
  2. Handler使用步骤:
    1) 在主线程(UI线程)中创建Handler的子类对象,并重写处理消息的回调方法。
    2) 在新启动的线程(非UI线程)中创建消息,并发送。

3.Handler原理:Android系统在启动一个Activity界面时,会为它创建一个消息循环(Looper)和消息队列(MessageQueue)。
1) Looper:消息循环(轮询器),负责从MessageQueue中取出消息(Message),并将消息分发到发送该消息的Handler对象
2) MessageQueue:用FIFO方式管理消息的消息队列。
3) Handler:负责把消息发送给Looper管理的MessageQueue,并负责处理Looper分发过来的消息。
prapare()方法:保证每个线程最多只有一个Looper对象。  
looper()方法:启动Looper,使用一个死循环不断取出MessageQueue中的消息,并将取出的消息分给对应的Handler进行处理。

Looper实现原理
Looper类里包含一个消息队列对象和一个线程对象。当创建Looper时,会自动创建一个消息队列,同时将内部线程对象指向创建Looper的线程。当开启Looper后(looper.loop()),会自动进入无限for循环中,不断去遍历消息队列,如果没有消息则阻塞,有消息则回调handler的handlemessage方法进行处理。

Looper.prepare()

首先,要使用Looper机制一般会在当前线程中创建Handler对象,里面会自动创建一个looper对象和消息队列,这里面的消息队列属于当前线程空间。但此时的looper还不会去遍历,也没有绑定到当前线程。其中,looper对象内部也包含一个空消息队列对象和空线程。通过Looper.prepare()方法,先让该消息队列指向当前线程的消息队列,让空线程也指向当前线程。从而实现了绑定。

handler机制

如何在子线程中使用Handler:
Handler本质是从当前的线程中获取到Looper来监听和操作MessageQueue,当其他线程执行完成后回调当前线程。
子线程需要先prepare()才能获取到Looper的,是因为在子线程只是一个普通的线程,其ThreadLoacl中没有设置过Looper,所以会抛出异常,而在Looper的prepare()方法中sThreadLocal.set(new Looper())是设置了Looper的。

class Rub implements Runnable {  
        public Handler myHandler;  
        // 实现Runnable接口的线程体 
        @Override  
        public void run() {  
         /*①、调用Looper的prepare()方法为当前线程创建Looper对象并,
          创建Looper对象时,它的构造器会自动的创建相对应的MessageQueue*/
            Looper.prepare();  
            
            /*.②、创建Handler子类的实例,重写HandleMessage()方法,该方法处理除当前线程以外线程的消息*/
             myHandler = new Handler() {  
                @Override  
                public void handleMessage(Message msg) {  
                    String ms = "";  
                    if (msg.what == 1) {  
                    }  
                }  
            };  
            //③、调用Looper的loop()方法来启动Looper让消息队列转动起来
            Looper.loop();  
        }
    }

创建线程的两种方式:

  1. 创建一个Thread对象(继承Thread类,重写run方法)
  2. 创建一个Runnable对象(实现Runnable接口,重写run方法),以这个对象来构造Thread对象。

另外除了发送消息之外,我们还有以下几种方法可以在子线程中进行UI操作:

  1. Handler的post()方法
  2. View的post()方法
  3. Activity的runOnUiThread()方法

你可能感兴趣的:(handler)