zoukankan      html  css  js  c++  java
  • 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()内部是个死循环,后面写的代码无法执行到。

  • 相关阅读:
    AjaxMethod js调用后台方法
    鼠标点击清空文本框 失去焦点显示提示信息
    js屏蔽BackSpace 返回上一页
    IE8标准模式打开网页
    Windows无法启动SQL server 代理服务(位于本地计算机上)错误1067:进程意外终止
    遍历枚举,添加进DropDownist
    文本框只能输入数字
    个人开发框架总结(五)
    从Power Design设计文档中提取Model
    FaibClass.WebControls控件详解(一)
  • 原文地址:https://www.cnblogs.com/chhom/p/5620396.html
Copyright © 2011-2022 走看看