zoukankan      html  css  js  c++  java
  • Android Handler Message总结一下

    当应用程序启动时,会开启一个主线程(也就是UI线程)。由她来管理UI。监听用户点击。来响应用户并分发事件等。所以一般在主线程中不要运行比較耗时的操作,如联网下载数据等,否则出现ANR错误。所以就将这些操作放在子线程中。可是因为AndroidUI线程是不安全的。所以仅仅能在主线程中更新UI。Handler就是用来 子线程和创建Handler的线程进行通信的。


             Handler的使用分为两部分:

             一部分是创建Handler实例,重载handleMessage方法,来处理消息。



    [java] view plaincopy
    1. mProgressHandler = new Handler()  
    2.         {  
    3.             public void handleMessage(Message msg)  
    4.             {  
    5.                 super.handleMessage(msg);  
    6.             }  
    7.         };  

             当然,也可继承自Handler,相同要实现handleMessage(Message msg)方法。


    [java] view plaincopy
    1. class MyHandler extends Handler {  
    2.         public MyHandler() {  
    3.         }  
    4.   
    5.         // 子类必须重写此方法,接受数据  
    6.         @Override  
    7.         public void handleMessage(Message msg) {  
    8.             // TODO Auto-generated method stub  
    9.             Log.d("MyHandler""handleMessage......");  
    10.             super.handleMessage(msg);  
    11.   
    12.         }  
    13.     }  

                  还有一部分是分发Message 或者Runable对象到Handler所在的线程中,一般Handler在主线程中。


                  Handler中分发消息的一些方法
              post(Runnable)
              postAtTime(Runnable,long)
              postDelayed(Runnable long)
              sendEmptyMessage(int what)
              sendMessage(Message)
              sendMessageAtTime(Message,long)
              sendMessageDelayed(Message,long)

                 handler本身不仅能够发送消息。还能够用post的方式加入一个实现Runnable接口的匿名对象到消息队列中。在目标收到消息后就能够回调的方式在自己的线程中运行run的方法体。


    Message

    [java] view plaincopy
    1. Message message = Message.obtain();  
    2.        message.arg1 = 1;  
    3. message.arg2 = 2;  
    4. message.obj = "Demo";  
    5. message.what = 3;  
    6. Bundle bundleData = new Bundle();  
    7. bundleData.putString("Name""Lucy");  
    8. message.setData(bundleData);  


    Message 能够传递的參数有:

    1. arg1 arg2 整数类型,是setData的低成本替代品。

    传递简单类型

    2. Object 类型 obj

    3. what  用户自己定义的消息代码。这样接受者能够了解这个消息的信息。每一个handler各自包括自己的消息代码,所以不用操心自己定义的消息跟其它handlers有冲突。

    4.其它的能够通过Bundle进行传递

         Message能够通过new Message构造来创建一个新的Message,可是这样的方式非常不好,不建议使用。

    最好使用Message.obtain()来获取Message实例,它创建了消息池来处理的。


          公共构造器

      public      Message()       

      构造器(可是获取Message对象的最好方法是调用Message.obtain())。

     

    例如以下这些通过Message.obtain方式获取Message实例,參数中传递了Handler,发送该消息时不再使用handler.sendMessage这样的方式。使用message.sendToTarget();只是归根究竟都是调用Handler.sendMessage进行发送消息。

    Message类中保存Handler实例。


    public static Message  obtain (Handler h, int what, int arg1, int arg2, Object obj)

    obtain()一样,可是设置了target, what, arg1, arg2obj的值。

             參数

                       h               设置的target

                       what        设置的what

                       arg1         设置的arg1

                       arg2         设置的arg2

                       obj            设置的obj

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Message  obtain (Handler h, int what, Object obj)

    obtain()一样,可是设置了target, whatobj的值。

             參数

                       h               设置的target

                       what       设置的what

                       obj            设置的obj

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Messageobtain (Handler h, int what)

    obtain()一样,可是设置了targetwhat的值。

             參数

                       h                target的值

                       what         what的值

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Message   obtain (Handler h)

    obtain()一样,可是设置了target的值

             參数

                       h               消息对象的target成员的值

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Message  obtain (Handler h, Runnable callback)

    obtain(Handler)一样,可是设置回调函数,在Message返回时调用。

             參数

                       h               消息对象的target成员的值

                       callback   当消息处理时会调用的回调函数

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Message   obtain ()

    从全局池中返回一个新的Message实例。在大多数情况下这样能够避免分配新的对象。

     

    public static Message   obtain (Handler h, int what, int arg1, int arg2)

    obtain()一样,可是设置了target, what, arg1arg2的值

             參数

                       h               设置的targe

                       what        设置的what

                       arg1         设置的arg1

                       arg2         设置的arg2

             返回值

                      从全局池中分配的一个Message对象。

     

    public static Message   obtain (Message obj)

    obtain()。可是从一个已存在的消息中拷贝值(包含它的目标)。

             參数

                       orig          要拷贝的源消息

             返回值

                      从全局池中分配的一个Message对象。

     

    public Bundle   peekData ()

    getData()相似,可是并不延迟创建Bundle。假设Bundle对象不存在返回null。很多其它信息见getData()

             參考

                       getData()

                       setData(Bundle)

     

    public void   recyle ()

    向全局池中返回一个Message实例。一定不能在调用此函数后再使用Message——它会马上被释放。

     

    public void  sendToTarget ()

    Handler发送此消息。getTarget()方法能够获取此Handler。假设这个字段没有设置会抛出个空指针异常。

     

    public void   setData (Bundle data)

    设置一个随意数据值的Bundle对象。

    假设能够,使用arg1arg2域发送一些整型值以降低消耗。

    參考

             getData()

             peekData()

     

    public void  setTarget (Handler target)

    设置将接收此消息的Handler对象。


                 




     PS:

            线程安全和线程不安全

            线程安全就是多线程訪问时,採用了加锁机系统。当一个线程访问一个数据类。保护,其他线程不能被访问,直到线程完成读,使用前其他线程。

    没有数据不一致或数据污染。


            线程安全是不提供数据访问保护,可能有一个以上的线程已使改变的数据而获得的数据是脏数据

  • 相关阅读:
    DNT论坛整合笔记二
    LINQ中的动态排序
    无法安装数据库关系图支持对象的解决方法
    总访问量,日访问量,周访问量统计代码
    ASP.NET 数据绑定控件和 Eval方法
    KindEditor ASP.NET 上传/浏览服务器 附源码
    地图定位 图吧地图定位 附javascript源码每行都有注释
    java.io.IOException: Unable to open sync connection!
    Canvas和Paint实例
    Android初级教程_获取Android控件的宽和高
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5036662.html
Copyright © 2011-2022 走看看