对Android Handler Message Looper常见用法,知识点的一些总结

Android 非UI线程中是不能更新UI的,Handler是Android 提供的一套更新UI的机制,也是用来发送消息和处理消息的一套机制。java

之前刚接触的Handler的时候,感受老是很困惑,对Handler原理也是只知其一;不知其二,如今对Handler常见用法,知识点总结一下。app

先看一下谷歌Android官方文档对Handler的描述:ide

 

Class Overview

 

A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue. 函数

 

它容许用户发送、处理消息和与线程的消息队列相关联的 runnable 对象。每个 handler 实例都与一个单独的线程相关联。每次建立一个新的 hander 对象时,它都与建立该对象的线程或者该线程中的消息队列绑定在一块儿,这样handler 就能够发送消息和 runable 对象到消息队列中,并在从消息队列中取出的时候处理它们。oop

 

 

1. Handler的构造函数

 

  • Handler()   Default constructor associates this handler with the Looper for the current thread.
  • Handler(Handler.Callback callback) Constructor associates this handler with theLooper for the current thread and takes a callback interface in which you can handle messages.
  •  
  •  

 

 

说明:   Handler()是最经常使用的一种post

 

   Handler(Handler.Callback callback)能够截获消息,this

   Handler(Looper looper)指定了Looper对象,在实际开发中经常使用HandlerThread.getLooper()。spa

 

2. 关于Message

 

 

Handler若是使用sendMessage的方式把消息入队到消息队列中,须要传递一个Message对象,而在Handler中,须要重 写handleMessage()方法,用于获取工做线程传递过来的消息。.net

发送消息常见的方式以下,用法大同小异。线程

 

 

Message的参数:

 

  • int what:定义的消息码,通常用于设定消息的标志。
  • int arg1:简单参数
  • int arg2:简单参数
  • Object obj:传递一个任意的对象。

 

移除Message

  • removeMessages(int what)   

    Remove any pending posts of messages 

     

    with code 'what' that are in the message queue.

 

 

 

3. 关于Post

 

 

Post 会传递一个Runnable对象到消息队列中

 

Post常见方法

 

 

  • post(Runnable r) Causes the Runnable r to be added to the message queue.
  • postDelayed(Runnable r, long delayMillis) Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses.
  • postAtTime(Runnable r,Object token, long uptimeMillis) Causes the Runnable r to be added to the message queue, to be run at a specific time given byuptimeMillis.

 

从消息队列中移除一个Runnable对象

removeCallbacks(Runnable r)Remove any pending posts of Runnable r that are in the message queue.

 

4. 关于MessageQueue

 

MessageQueue 是消息队列,在MainThread建立的时候会建立一个Looper,在建立Looper的时候,会建立MessageQueue();

 

5. 关于Looper

 

      Looper.loop()是一个死循环,用来循环查询消息队列,并把消息回传给handler。

 

 

    

6. Demo说明

 

 

 

1.1 发送空消息和移除消息,这里以sendEmptyMessageDelayed()为例

[java] view plain copy

  1. public class Test1 extends Activity implements OnClickListener {  
  2.   
  3.     private TextView tv;  
  4.     private Button btn;  
  5.     private int i = 0;  
  6.   
  7.     Handler handler = new Handler() {  
  8.         public void handleMessage(Message msg) {  
  9.             tv.setText("Hello 改变了"+i++);  
  10.             handler.sendEmptyMessageDelayed(0, 1 * 1000); //延迟一秒发送  
  11.   
  12.         };  
  13.     };  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.test1);  
  19.         setView();  
  20.         test1();  
  21.   
  22.     }  
  23.   
  24.     private void setView() {  
  25.         tv = (TextView) this.findViewById(R.id.tv);  
  26.         btn = (Button) this.findViewById(R.id.btn);  
  27.         btn.setOnClickListener(this);  
  28.     }  
  29.   
  30.     private void test1() {  
  31.   
  32.         new Thread() {  
  33.             public void run() {  
  34.   
  35.                 handler.sendEmptyMessageDelayed(0, 1 * 1000); //延迟一秒发送  
  36.             };  
  37.         }.start();  
  38.     }  
  39.   
  40.     @Override  
  41.     public void onClick(View v) {  
  42.         switch (v.getId()) {  
  43.   
  44.         case R.id.btn:  
  45.             handler.removeMessages(0);//移除消息  
  46.             break;  
  47.   
  48.         default:  
  49.             break;  
  50.         }  
  51.   
  52.     }  
  53.   
  54. }  

 

效果图,数字每隔一秒,自增1,点击,数字会中止自增:


 

1.2 使用new Message(),并给Message赋值,使用handler.sendMessage(msg)发送

[java] view plain copy

  1. public class Test2 extends Activity implements OnClickListener {  
  2.   
  3.     private TextView tv;  
  4.   
  5.   
  6.     Handler handler = new Handler() {  
  7.         public void handleMessage(Message msg) {  
  8.               
  9.             tv.setText("msg.what=" + msg.what + ",     msg.arg1=" + msg.arg1  
  10.                     + ",    msg.arg2=" + msg.arg2 + ",    msg.obj=" + msg.obj);  
  11.   
  12.         };  
  13.     };  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.test2);  
  19.         setView();  
  20.         test();  
  21.   
  22.     }  
  23.   
  24.     private void setView() {  
  25.         tv = (TextView) this.findViewById(R.id.tv);  
  26.   
  27.     }  
  28.   
  29.     private void test() {  
  30.   
  31.         new Thread() {  
  32.             public void run() {  
  33.   
  34.                 Message msg = new Message();  
  35.                 UserBean userBean = new UserBean();  
  36.                 userBean.setName("Jim");  
  37.                 userBean.setPwd("123456");  
  38.                 msg.what = 1;  
  39.                 msg.arg1 = 2;  
  40.                 msg.arg2 = 3;  
  41.                 msg.obj = userBean;  
  42.                 handler.sendMessage(msg);  
  43.             };  
  44.         }.start();  
  45.     }  
  46.   
  47.     @Override  
  48.     public void onClick(View v) {  
  49.         switch (v.getId()) {  
  50. //  
  51. //      case R.id.btn:  
  52. //          handler.removeMessages(0);//移除消息  
  53. //          break;  
  54.   
  55.         default:  
  56.             break;  
  57.         }  
  58.   
  59.     }  
  60.   
  61. }  

实体类

[java] view plain copy

  1. public class UserBean {  
  2.   
  3.     public String name;  
  4.       
  5.     public String pwd;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.   
  15.     public String getPwd() {  
  16.         return pwd;  
  17.     }  
  18.   
  19.     public void setPwd(String pwd) {  
  20.         this.pwd = pwd;  
  21.     }  
  22.   
  23.     @Override  
  24.     public String toString() {  
  25.         return "UserBean [name=" + name + ", pwd=" + pwd + "]";  
  26.     }  
  27.       
  28.       
  29. }  

 

效果图以下,能够看到消息成功传递和接收。

 

1.3 使用obtainMessage()获取已绑定的消息,并给Message赋值,使用msg.sendToTarget()发送

[java] view plain copy

  1. public class Test3 extends Activity implements OnClickListener {  
  2.   
  3.     private TextView tv;  
  4.   
  5.     Handler handler = new Handler() {  
  6.         public void handleMessage(Message msg) {  
  7.   
  8.             tv.setText("msg.what=" + msg.what + ",     msg.arg1=" + msg.arg1  
  9.                     + ",    msg.arg2=" + msg.arg2 + ",    msg.obj=" + msg.obj);  
  10.   
  11.         };  
  12.     };  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.test3);  
  18.         setView();  
  19.         test();  
  20.   
  21.     }  
  22.   
  23.     private void setView() {  
  24.         tv = (TextView) this.findViewById(R.id.tv);  
  25.   
  26.     }  
  27.   
  28.     private void test() {  
  29.   
  30.         new Thread() {  
  31.             public void run() {  
  32.   
  33.                 // Message msg = new Message();  
  34.                 Message msg = handler.obtainMessage();  
  35.                 UserBean userBean = new UserBean();  
  36.                 userBean.setName("Jim");  
  37.                 userBean.setPwd("123456");  
  38.                 msg.what = 1;  
  39.                 msg.arg1 = 2;  
  40.                 msg.arg2 = 3;  
  41.                 msg.obj = userBean;  
  42.                 // handler.sendMessage(msg);n  
  43.                 msg.sendToTarget();  
  44.             };  
  45.         }.start();  
  46.     }  
  47.   
  48.     @Override  
  49.     public void onClick(View v) {  
  50.         switch (v.getId()) {  
  51.         //  
  52.         // case R.id.btn:  
  53.         // handler.removeMessages(0);//移除消息  
  54.         // break;  
  55.   
  56.         default:  
  57.             break;  
  58.         }  
  59.   
  60.     }  
  61.   
  62. }  


效果和上图同样

2 Post 会传递一个Runnable对象到消息队列中

2.1 使用Post方式传递一个Runnable对象到消息队列和移除

[java] view plain copy

  1. public class Test4 extends Activity implements OnClickListener {  
  2.   
  3.     private TextView tv;  
  4.     private Button btn;  
  5.     private int i = 0;  
  6.   
  7.     Handler handlerPost = new Handler();  
  8.     // 线程中运行该接口的run函数  
  9.     Runnable update_thread = new Runnable() {  
  10.         public void run() {  
  11.             // System.out.println("activity_id---->"+Thread.currentThread().getId());  
  12.             // System.out.println("activity_name---->"+Thread.currentThread().getName());  
  13.             tv.setText("handlerPost:"+i++);  
  14.             // 延时1s后又将线程加入到线程队列中  
  15.             handlerPost.postDelayed(update_thread, 1000);  
  16.   
  17.         }  
  18.     };  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.test4);  
  24.         setView();  
  25.         System.out  
  26.                 .println("activity_id0---->" + Thread.currentThread().getId());  
  27.         System.out.println("activity_name0---->"  
  28.                 + Thread.currentThread().getName());  
  29.         test();  
  30.   
  31.     }  
  32.   
  33.     private void setView() {  
  34.         tv = (TextView) this.findViewById(R.id.tv);  
  35.         btn = (Button) this.findViewById(R.id.btn);  
  36.         btn.setOnClickListener(this);  
  37.     }  
  38.   
  39.     private void test() {  
  40.   
  41.         // 将线程接口马上送到线程队列中  
  42.         handlerPost.post(update_thread); // handler使用了post方法启动了runnbale,其实启动的线程和activity主线程是同一个线程  
  43.         // Thread t = new Thread(update_thread);  
  44.         // //这样绑定的线程与它所在的activity线程就不是同一个线程了  
  45.         // t.start();  
  46.     }  
  47.   
  48.     @Override  
  49.     public void onClick(View v) {  
  50.         switch (v.getId()) {  
  51.   
  52.         case R.id.btn:  
  53.             handlerPost.removeCallbacks(update_thread);// 将接口从线程队列中移除  
  54.             break;  
  55.   
  56.         default:  
  57.             break;  
  58.         }  
  59.   
  60.     }  
  61.   
  62. }  

说明:
handler使用了post方法启动了runnbale,其实启动的线程和activity主线程是同一个线程

若是使用

Thread t = new Thread(update_thread);

t.start();

这样绑定的线程与它所在的activity线程就不是同一个线程了

效果图:

 

3   Handler(Looper looper)的使用,使用handThread.getLooper()做为参数。

 注意:若是 thread.getLooper()中的thread为子线程,则会报空指针异常,由于当主线程执行Handler(Looper looper)

的时候,子线程的Looper对象还未创立。

 

[java] view plain copy

  1. public class Test5 extends Activity implements OnClickListener {  
  2.   
  3.     private TextView tv;  
  4.     HandlerThread handThread;  
  5.     Handler handler;  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.test5);  
  11.         setView();  
  12.         test();  
  13.   
  14.     }  
  15.   
  16.     private void setView() {  
  17.         tv = (TextView) this.findViewById(R.id.tv);  
  18.   
  19.     }  
  20.   
  21.     private void test() {  
  22.           
  23.         // HandlerThread  
  24.         handThread = new HandlerThread("handThread");  
  25.         handThread.start();  
  26.         handler = new Handler(handThread.getLooper()) {  
  27.             public void handleMessage(Message msg) {  
  28.   
  29.                 tv.setText("HandlerThread");  
  30.   
  31.             };  
  32.         };  
  33.         handler.sendEmptyMessage(0);  
  34.     }  
  35.   
  36.     @Override  
  37.     public void onClick(View v) {  
  38.         switch (v.getId()) {  
  39.         //  
  40.         // case R.id.btn:  
  41.         // handler.removeMessages(0);//移除消息  
  42.         // break;  
  43.   
  44.         default:  
  45.             break;  
  46.         }  
  47.   
  48.     }  
  49.   
  50. }  


效果图:

 

Demo下载地址:http://download.csdn.net/detail/yalinfendou/8477587

相关文章
相关标签/搜索