012android初级篇之Handler机制

设计Handler类的目的

Handler类被用来注册到一个线程中,这样可以提供一个简单的通信渠道,用来发送数据到这个线程。
可作为UI线程与后台线程交互的几种方法之一。

具体用途

  1. 消息的分发和处理,安排 messages 和 runnables在未来某个时刻被执行;
  2. 队列action在其他线程上被执行;

与之相关的类:looper类,

looper 主要功能是为特定单一线程运行一个消息环。

  1. 一个线程对应一个looper。同样一个looper对应一个线程。这就是所谓的特定单一;

  2. 一般情况下,在一个线程创建时他本身是不会产生他特定单一的looper的(主线程是个例外)。因此我们需要手动的把一个looper与线程相关联。其方法只需在需要关联的looper的线程中调用Looper.prepare。之后我们再调用Looper.loop启动looper。
    如下例子:

     class NetWorkThread implements Runnable 
     {
         public MyHandler mHandler =new MyHandler();
         @Override
         public void run() {
     
             Looper.prepare();
             //mHandler =new MyHandler();
             Looper.loop();
         }
     }
    
  3. 具体的说,在我们将特定单一looper与线程关联的时候,looper会同时生产一个messageQueue。他是一个消息队列,looper会不停的从messageQuee中取出消息,也就是message。然后线程就会根据message中的内容进行相应的操作。

  4. looper和handler并非一一对应的。一个looper可以对应多个handler,而一个handler只能对应一个looper。handler和looper的绑定,是在构建handler的时候实现的,具体查询handler的构造函数。

  5. message,虽然我们可以自己创建一个新的message,但是更加推荐的是调用handler的obtainMessage方法来获取一个message。这个方法的作用是从系统的消息池中取出一个message,这样就可以避免message创建和销毁带来的资源浪费了。

假设A线程要传递信息给B线程,我们需要做的就是

  1. 在B线程中调用Looper.prepare和Looper.loop。(主线程不需要)
  2. 编写Handler类,重写其中的handleMessage方法。
  3. 创建Handler类的实例,并绑定looper
  4. 调用handler的sentMessage方法发送消息。

实例代码

NetWorkThread mNetWorkThread =new NetWorkThread();
new Thread(mNetWorkThread).start();
Message msg = mNetWorkThread.mHandler.obtainMessage();
msg.arg1=12;
mNetWorkThread.mHandler.sendMessage(msg);

Message相关

Message的使用样例

Message message = Message.obtain();  
message.arg1 = 1;  
message.arg2 = 2;  
message.obj = "Demo";  
message.what = 3;  
Bundle bundleData = new Bundle();  
bundleData.putString("Name", "Lucy");  
message.setData(bundleData);  

Message可以传递的参数有

  1. public int arg1 arg2 整数类型,是setData的低成本替代品。传递简单类型
  2. public Object object 类型
  3. public int what 用户自定义的消息代码,这样接受者可以了解这个消息的信息。每个handler各自包含自己的消息代码,所以不用担心自定义的消息跟其他handlers有冲突。
  4. 其他的可以通过Bundle进行传递

Message的构造函数

Message可以通过new Message构造来创建一个新的Message,但是这种方式很不好,不建议使用。最好使用Message.obtain()来获取Message实例,它从消息池获取。

参考链接

  1. Android开发中Handler的经典总结
  2. Android background processing with Handlers, AsyncTask and Loaders - Tutorial
  3. Android中UI线程与后台线程交互设计的5种方法
  4. Java中Runnable和Thread的区别
  5. Android:主线程如何向子线程发送消息
  6. android parcelable 详解
posted @ 2015-11-06 11:17  夏大王  阅读(234)  评论(0编辑  收藏  举报