Android Handler

一、android中为什么使用多线程

    Android中主线程不能执行耗时操作、不能访问网络等。这些动作会导致主线程被阻塞,容易引起ANR(Application no response)异常。所以必须把访问网络、耗时操作等放入到子线程中执行。Android的主线程(UI线程)是线程不安全的,所以当各个子线程获得数据之后不能直接修改UI,必须把修改UI的权利交给主线程。

     AsyncTask、Loader都可以启动子线程,并且可以把修改的UI的任务交给主线程完成。Handler(消息机制)也可以完成。

二、Handler

  Handler类的主要作用有两个:

  1. 利用Handler对象,再启动的新线程中发送消息
  2. 在主线程中处理从别的线程发来的消息。

  Handler的使用方式:

  1. 一般在主线程中创建Handler对象,并覆盖Handler的方法(如果不需要处理消息也可以不覆写):void handleMessage(Message msg)。在该方法中对收到的信息进行处理,一般是修改UI的动作。
  2. 在另外的线程中使用Handler对象的sendXX(Message msg)方法来发送消息,则handlerMessage方法就可以接收到此处发送的消息。

三、Message

   Handler发送的数据均需要封装在Message对象中

   Message共有四个主要公共属性:

   public int argue1;

   public int arg2;

   以上是两个int型整数,当传递的信息是int整数时,优选使用这两个参数传递。

   public object obj;

   当传递的是一个对象的时候,优先使用这个属性来传递

   public int what;

   一个int型整数,用来区别Message类型,主要是用于接收的地方可以判断是谁发送的

  

  注意:Message对象虽然可以通过构造器来创建,但是处于效率考虑不建议这么做,而是调用Message的静态方法obtain()(多个重载)来获得Message对象。另外更多时候,为了便利,会直接调用handler对象的obtainMessage()方法,该方法内部仍然会调用Message.obtain();

四、Handler、Looper(轮播器)、MessageQueue(消息队列)、Message(消息)工作原理

 与handler一起工作的几个组件

  1. Message:Handler接收和处理的消息对象。
  2. MessageQueue:消息队列,它采用先进先出的方式来管理Message。Handler发送消息时先把消息发送到消息队列中。
  3. Looper:每个线程最多拥有一个Looper,他的Loop方法负责读取MessageQueue队列中的消息,读到信息之后就把信息交给发送该消息的Handler进行处理。程序在创建Looper对象的时候,会自动在Looper的构造器中自动创建一个MessageQueue队列对象。

   注意:

  1、 Handler发送的消息时先放入MessageQueue,所以handler要正常工作,必须当前线程先有MessageQueue

  2、 而MessageQueue是由Looper管理的,所以换句话说,Handler要正常工作必须先有Looper

  3、 为了保证线程中有Looper,分两种情况。

      A:在主线程中系统默认已经初始化了一个Looper对象,并且已经loop(),所以在主线程中可以直接创建Handler对象进行使用。

      B:程序员自己创建的子线程,必须手动创建一个Looper对象,并启动它。

              Looper.prepare();  //创建Looper对象,同时初始化一个消息队列

              Looper.loop()//启动Looper

总结:

  1. 主线程中使用Handler直接创建及可以使用。
  2. 子线程使用Handler的步骤:
    1. 调用Loop.prepare();
    2. 创建Handler对象
    3. 调用Looper.loop();

     注意:在线程中调用过Looper.loop()之后,后面不能在写代码,因为loop()内部是个死循环,后面写的代码无法执行到。

posted @ 2016-06-27 15:48  ChHM  阅读(175)  评论(0编辑  收藏  举报