码迷,mamicode.com
首页 > 移动开发 > 详细

zz android 中的handler

时间:2016-04-22 18:23:11      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

A Handler allows you to send and process Message and Runnable objects associated with a thread‘s MessageQueue. 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.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

一个Handler允许你发送和处理消息(Message)以及与一个线程的消息队列相关的Runnable对象。每个Handler实例都和单个线程以及该线程的消息队列有关。当你创建了一个新Handler,它就会和创建它的线程/消息队列绑定,在那以后,它就会传递消息以及runnable对象给消息队列,然后执行它们。

 

      需要使用Handler有两大主要的原因:

      (1)在将来的某个时间点调度处理消息和runnable对象;

      (2)将需要执行的操作放到其他线程之中,而不是自己的;

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler‘s handleMessage(Message) method (requiring that you implement a subclass of Handler).

 调度处理消息是通过调用post(Runnable), postAtTime(Runnable, long),postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message),sendMessageAtTime(Message, long)和sendMessageDelayed(Message,long)等方法完成的。其中的post版本的方法可以让你将Runnable对象放进消息队列;sendMessage版本的方法可以让你将一个包含有bundle对象的消息对象放进消息队列,然后交由handleMessage(Message)方法处理。(这个需要你复写Handler的handleMessage方法)

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler‘s message queue and processed when appropriate. 

 Handler在实际开发中是很常用的,主要是用来接收子线程发送的数据,然后主线程结合此数据来更新界面UI。

     Android应用程序启动时,他会开启一个主线程(也就是UI线程),管理界面中的UI控件,进行事件派发。

你必需要知道的:

若在主线程中实例化一个Handler对象,例如:

     Handler mHandler = newHandler();

     此时它并没有新派生一个线程来执行此Handler,而是将此Handler附加在主线程上,故此时若你在Handler中执行耗时操作的话,还是会弹出ANR对话框!

  1.      super.onCreate(savedInstanceState);     
  2.         setContentView(R.layout.main);     
  3.              
  4.         mContext = this;     
  5.     
  6.         Log.i(TAG, "Main thread id = " +      
  7.                 Thread.currentThread().getId());     
  8.              
  9.         btnStart = (Button) findViewById(R.id.btn_start);     
  10.         btnStart.setOnClickListener(this);     
  11.         btnStop = (Button) findViewById(R.id.btn_stop);     
  12.         btnStop.setOnClickListener(this);     
  13.     }     
  14.          
  15.     @Override    
  16.     public void onClick(View view) {     
  17.         switch (view.getId()) {     
  18.         case R.id.btn_start:     
  19.             mHandler.postDelayed(workRunnable, DELAY_TIME);     
  20.             break;     
  21.         case R.id.btn_stop:     
  22.             mHandler.removeCallbacks(workRunnable);     
  23.             break;     
  24.         }     
  25.     }     
    1.  Runnable workRunnable = new Runnable() {     
    2.         int counter = 0;     
    3.              
    4.         public void run() {     
    5.             if (counter++ < 1) {     
    6.                 Log.i(TAG, "workRunnable thread id = " +      
    7.                         Thread.currentThread().getId());     
    8.                 mHandler.postDelayed(workRunnable, DELAY_TIME);     
    9.             }     
    10.         }     
    11.     };     
    12.          
    13.     Handler mHandler = new Handler();     
    14. }
    15. 发现thread id是相同的,这就说明:默认情况下创建的Handler会绑定到主线程上,你不能做太耗时的操作

    16. -----------------------------------------------------------------------------------------------------------------------
      模式一、用HandlerThread来建新线程,
      Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
        HandlerThread(String name)
        HandlerThread(String name, int priority)
      Constructs a HandlerThread.
      Looper getLooper()
      This method returns the Looper associated with this thread.
      1.  public void onCreate(Bundle savedInstanceState) {     
      2.         super.onCreate(savedInstanceState);     
      3.         HandlerThread handlerThread = new HandlerThread("myHandlerThread");     
      4.         handlerThread.start();     
      5.         handler = new Handler(handlerThread.getLooper());     
      6.         handler.post(new MyRunnable());     
      7.         System.out.println("Oncreate---The Thread id is :"    
      8.                 + Thread.currentThread().getId());     
      9.         setContentView(R.layout.main);     
      10.     }     
      11.     private class MyRunnable implements Runnable {     
      12.         public void run() {     
      13.             System.out.println("Runnable---The Thread is running");     
      14.             System.out.println("Runnable---The Thread id is :"    
      15.                     + Thread.currentThread().getId());     
      16.             try {     
      17.                 Thread.sleep(6000);     
      18.             } catch (InterruptedException e) {     
      19.                 // TODO Auto-generated catch block    
      20.                 e.printStackTrace();     
      21.             }     
      22.         }     这个就是不同线程了
        模式二、sendmessage,默认还是主线程,例子:
        1.  Handler mHandler = new Handler() {     
        2.             // 注意:在各个case后面不能做太耗时的操作,否则出现ANR对话框     
        3.             @Override    
        4.             public void handleMessage(Message msg) {     
        5.                 switch (msg.what) {     
        6.                 case TASK_BEGIN:     
        7.                     Log.i(TAG, "[H_TID:" +     
        8.                         Thread.currentThread().getId() + "] Get TASK_BEGIN");     
        9.                     break;     
        10.                          
        11.                 case TASK_1:     
        12.                     Log.i(TAG, "[H_TID:" +     
        13.                         Thread.currentThread().getId() + "] Get TASK_1");     
        14.                     break;     
        15.                          
        16.                 case TASK_2:     
        17.                     Log.i(TAG, "[H_TID:" +     
        18.                         Thread.currentThread().getId() + "] Get TASK_2");     
        19.                     break;     
        20.                          
        21.                 case TASK_END:     
        22.                     Log.i(TAG, "[H_TID:" +     
        23.                         Thread.currentThread().getId() + "] Get TASK_END");     
        24.                     finish();     
        25.                     break;     
        26.                 }     
        27.                 super.handleMessage(msg);     
        28.             }     
        29.         };     
          1.    public void onClick(View view) {     
          2.             switch (view.getId()) {     
          3.             case R.id.btn_start:     
          4.                 // 启动任务(消息只有标识,立即投递)     
          5.                 mHandler.sendEmptyMessage(TASK_BEGIN);     
          6.                 Log.i(TAG, "Send TASK_BEGIN to handler.");     
          7.                      
          8.                 // 开始任务1(在mHandler的消息队列中获取一个Message对象,避免重复构造)     
          9.                 Message msg1 = mHandler.obtainMessage(TASK_1);     
          10.                 msg1.obj = "This is task1";     
          11.                 mHandler.sendMessage(msg1);     
          12.                 Log.i(TAG, "Send TASK_1 to handler.");     
          13.                      
          14.                 // 开启任务2(和上面类似)     
          15.                 Message msg2 = Message.obtain();     
          16.                 msg2.arg1 = 10;     
          17.                 msg2.arg2 = 20;     
          18.                 msg2.what = TASK_2;     
          19.                 mHandler.sendMessage(msg2);     
          20.                 Log.i(TAG, "Send TASK_2 to handler.");     
          21.                 break;     
          22.                      
          23.             case R.id.btn_stop:     
          24.                 // 结束任务(空消息体,延时2s投递)     
          25.                 mHandler.sendEmptyMessageDelayed(TASK_END, 2000);     
          26.                 Log.i(TAG, "Send TASK_END to handler.");     
          27.                 break;     
          28.             }     
          29.     }     
          30.     }  </span>  
            消息队列仍绑定在主线程上,但在子线程中发送消息。
          1.  Thread workThread = new Thread() {     
          2.             // 你可以在run方法内做任何耗时的操作,然后将结果以消息形式投递到主线程的消息队列中     
          3.             @Override    
          4.             public void run() {     
          5.                 // 启动任务(消息只有标识,立即投递)     
          6.                 mHandler.sendEmptyMessage(TASK_BEGIN);     
          7.                 Log.i(TAG, "[S_TID:" + Thread.currentThread().getId() + "]" +     
          8.                         "Send TASK_START to handler.");     
          9.                      
          10.                 // 开始任务1(在mHandler的消息队列中获取一个Message对象,避免重复构造)     
          11.                 Message msg1 = mHandler.obtainMessage(TASK_1);     
          12.                 msg1.obj = "This is task1";     
          13.                 mHandler.sendMessage(msg1);     
          14.                 Log.i(TAG, "[S_TID:" + Thread.currentThread().getId() + "]" +     
          15.                         "Send TASK_1 to handler.");     
          16.                      
          17.                 // 开启任务2(和上面类似)     
          18.                 Message msg2 = Message.obtain();     
          19.                 msg2.arg1 = 10;     
          20.                 msg2.arg2 = 20;     
          21.                 msg2.what = TASK_2;     
          22.                 mHandler.sendMessage(msg2);     
          23.                 Log.i(TAG, "[S_TID:" + Thread.currentThread().getId() + "]" +     
          24.                         "Send TASK_2 to handler.");     
          25.                      
          26.                 // 结束任务(空消息体,延时2s投递)     
          27.                 mHandler.sendEmptyMessageDelayed(TASK_END, 2000);     
          28.                 Log.i(TAG, "[S_TID:" + Thread.currentThread().getId() + "]" +     
          29.                         "Send TASK_END to handler.");     
          30.             }     
          31.         };     
          将消息队列绑定到子线程上,主线程只管通过Handler往子线程的消息队列中投递消息即可
        1.  public void onCreate(Bundle savedInstanceState) {     
        2.         super.onCreate(savedInstanceState);     
        3.         setContentView(R.layout.main);     
        4.     
        5.         Log.i(TAG, "[M_TID:" + Thread.currentThread().getId() + "]" +     
        6.                 "This is in main thread.");     
        7.              
        8.         HandlerThread myLooperThread = new HandlerThread("my looper thread");     
        9.         myLooperThread.start();     
        10.              
        11.         Looper looper = myLooperThread.getLooper();     
        12.         mHandler = new MyHandler(looper);     
        13.              
        14.         // 启动任务(消息只有标识,立即投递)     
        15.         mHandler.sendEmptyMessage(TASK_BEGIN);     
        16.         Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +     
        17.                 "Send TASK_START to handler.");     
        18.              
        19.         // 开始任务1(在mHandler的消息队列中获取一个Message对象,避免重复构造)     
        20.         Message msg1 = mHandler.obtainMessage(TASK_1);     
        21.         msg1.obj = "This is task1";     
        22.         mHandler.sendMessage(msg1);     
        23.         Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +     
        24.                 "Send TASK_1 to handler.");     
        25.              
        26.         // 开启任务2(和上面类似)     
        27.         Message msg2 = Message.obtain();     
        28.         msg2.arg1 = 10;     
        29.         msg2.arg2 = 20;     
        30.         msg2.what = TASK_2;     
        31.         mHandler.sendMessage(msg2);     
        32.         Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +     
        33.                 "Send TASK_2 to handler.");     
        34.              
        35.         // 结束任务(空消息体,延时2s投递)     
        36.         mHandler.sendEmptyMessageDelayed(TASK_END, 2000);     
        37.         Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +     
        38.                 "Send TASK_END to handler.");     
        39.     }     
        40.          
        41.     class MyHandler extends Handler {     
        42.         public MyHandler(Looper looper) {     
        43.             super(looper);     
        44.         }     
        45.              
        46.         // 现在在每个case之后,你可以做任何耗时的操作了     
        47.         @Override    
        48.         public void handleMessage(Message msg) {     
        49.             switch (msg.what) {     
        50.             case TASK_BEGIN:     
        51.                 Log.i(TAG, "[H_TID:" +     
        52.                     Thread.currentThread().getId() + "] Get TASK_BEGIN");     
        53.                 break;     
        54.                      
        55.             case TASK_1:     
        56.                 Log.i(TAG, "[H_TID:" +     
        57.                     Thread.currentThread().getId() + "] Get TASK_1");     
        58.                 break;     
        59.                      
        60.             case TASK_2:     
        61.                 Log.i(TAG, "[H_TID:" +     
        62.                     Thread.currentThread().getId() + "] Get TASK_2");     
        63.                 break;     
        64.                      
        65.             case TASK_END:     
        66.                 Log.i(TAG, "[H_TID:" +     
        67.                     Thread.currentThread().getId() + "] Get TASK_END");     
        68.                 finish();     
        69.                 break;     
        70.             }     
        71.             super.handleMessage(msg);     
        72.         }     
        73.     }     
        74. }    
        自己创建新的线程,然后在新线程中创建Looper,主线程调用子线程中的发消息方法,将消息发给子线程的消息队列
        1.     super.onCreate(savedInstanceState);  
        2.         setContentView(R.layout.main);  
        3.   
        4.         Log.i(TAG, "[M_TID:" + Thread.currentThread().getId() + "]" +  
        5.                 "This is in main thread.");  
        6.           
        7.         LooperThread testThread = new LooperThread();  
        8.         testThread.start();  
        9.           
        10.         // 注意,这里需要等待一下,防止出现空指针异常  
        11.         while (null == workHandler) {  
        12.         }  
        13.           
        14.         testThread.sendMessageTodoYourWork();  
        15.     }  
        16.       
        17.     class LooperThread extends Thread {  
        18.         @Override  
        19.         public void run() {  
        20.             Looper.prepare();  
        21.               
        22.             workHandler = new Handler() {  
        23.                 // 现在在每个case之后,你可以做任何耗时的操作了  
        24.                 @Override  
        25.                 public void handleMessage(Message msg) {  
        26.                     switch (msg.what) {  
        27.                     case TASK_BEGIN:  
        28.                         Log.i(TAG, "[H_TID:" +  
        29.                            Thread.currentThread().getId() + "] Get TASK_BEGIN");  
        30.                         break;  
        31.                           
        32.                     case TASK_1:  
        33.                         Log.i(TAG, "[H_TID:" +  
        34.                            Thread.currentThread().getId() + "] Get TASK_1");  
        35.                         break;  
        36.                           
        37.                     case TASK_2:  
        38.                         Log.i(TAG, "[H_TID:" +  
        39.                            Thread.currentThread().getId() + "] Get TASK_2");  
        40.                         break;  
        41.                           
        42.                     case TASK_END:  
        43.                         Log.i(TAG, "[H_TID:" +  
        44.                            Thread.currentThread().getId() + "] Get TASK_END");  
        45.                         Looper.myLooper().quit();  
        46.                         finish();  
        47.                         break;  
        48.                     }  
        49.                     super.handleMessage(msg);  
        50.                 }  
        51.             };  
        52.               
        53.             Looper.loop();  
        54.         }  
        55.           
        56.         public void sendMessageTodoYourWork() {  
        57.             Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +  
        58.                 "Send TASK_START to handler.");  
        59.             // 启动任务(消息只有标识,立即投递)  
        60.             workHandler.sendEmptyMessage(TASK_BEGIN);  
        61.   
        62.             Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +  
        63.                 "Send TASK_1 to handler.");  
        64.             // 开始任务1(在workHandler的消息队列中获取一个Message对象,避免重复构造)  
        65.             Message msg1 = workHandler.obtainMessage(TASK_1);  
        66.             msg1.obj = "This is task1";  
        67.             workHandler.sendMessage(msg1);  
        68.               
        69.             Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +  
        70.                 "Send TASK_2 to handler.");           
        71.             // 开启任务2(和上面类似)  
        72.             Message msg2 = Message.obtain();  
        73.             msg2.arg1 = 10;  
        74.             msg2.arg2 = 20;  
        75.             msg2.what = TASK_2;  
        76.             workHandler.sendMessage(msg2);  
        77.   
        78.             Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" +  
        79.                 "Send TASK_END to handler.");  
        80.             // 结束任务(空消息体,延时2s投递)  
        81.             workHandler.sendEmptyMessageDelayed(TASK_END, 2000);  
        82.         }  
        83.     }  
        84. }  
          、主/子线程均有一个消息队列,然后相互传递消息(这种方式是最灵活的,双向传递,也不复杂)
          1. public void onCreate(Bundle savedInstanceState) {  
          2.         super.onCreate(savedInstanceState);  
          3.         setContentView(R.layout.main);  
          4.   
          5.         Log.i(TAG, "[M_TID:" + Thread.currentThread().getId() + "]" +  
          6.                 "This is in main thread.");  
          7.           
          8.         LooperThread testThread = new LooperThread();  
          9.         testThread.start();  
          10.           
          11.         // 注意,这里需要等待一下,防止出现空指针异常  
          12.         while (null == workHandler) {  
          13.         }  
          14.           
          15.         testThread.sendMessageTodoYourWork();  
          16.     }  
          17.     
          18.     Handler mainHandler = new Handler () {  
          19.         // 在每个case之后,不能做耗时的操作  
          20.         @Override  
          21.         public void handleMessage(Message msg) {  
          22.             switch (msg.what) {  
          23.             case TASK_BEGIN_OVER:  
          24.                 Log.i(TAG, "[MH_TID:" +  
          25.                     Thread.currentThread().getId() + "] TASK_BEGIN_OVER");  
          26.                 break;  
          27.                   
          28.             case TASK_1_OVER:  
          29.                 Log.i(TAG, "[MH_TID:" +  
          30.                     Thread.currentThread().getId() + "] TASK_1_OVER");  
          31.                 break;  
          32.                   
          33.             case TASK_2_OVER:  
          34.                 Log.i(TAG, "[MH_TID:" +  
          35.                     Thread.currentThread().getId() + "] TASK_2_OVER");  
          36.                 break;  
          37.                   
          38.             case TASK_END_OVER:  
          39.                 Log.i(TAG, "[MH_TID:" +  
          40.                     Thread.currentThread().getId() + "] TASK_END_OVER");  
          41.                 finish();  
          42.                 break;  
          43.             }  
          44.             super.handleMessage(msg);  
          45.         }  
          46.     };  
          47.       
          48.     class LooperThread extends Thread {  
          49.         @Override  
          50.         public void run() {  
          51.             Looper.prepare();  
          52.               
          53.             workHandler = new Handler() {  
          54.                 // 现在在每个case之后,你可以做任何耗时的操作了  
          55.                 @Override  
          56.                 public void handleMessage(Message msg) {  
          57.                     switch (msg.what) {  
          58.                     case TASK_BEGIN:  
          59.                         Log.i(TAG, "[ZH_TID:" +  
          60.                            Thread.currentThread().getId() + "] Get TASK_BEGIN");  
          61.                         // 做完之后报告信息给主线程  
          62.                         mainHandler.sendEmptyMessage(TASK_BEGIN_OVER);  
          63.                         break;  
          64.                           
          65.                     case TASK_1:  
          66.                         Log.i(TAG, "[ZH_TID:" +  
          67.                            Thread.currentThread().getId() + "] Get TASK_1");  
          68.                         // 做完之后报告信息给主线程  
          69.                         mainHandler.sendEmptyMessage(TASK_1_OVER);  
          70.                         break;  
          71.                           
          72.                     case TASK_2:  
          73.                         Log.i(TAG, "[ZH_TID:" +  
          74.                            Thread.currentThread().getId() + "] Get TASK_2");  
          75.                         // 做完之后报告信息给主线程  
          76.                         mainHandler.sendEmptyMessage(TASK_2_OVER);  
          77.                         break;  
          78.                           
          79.                     case TASK_END:  
          80.                         Log.i(TAG, "[ZH_TID:" +  
          81.                            Thread.currentThread().getId() + "] Get TASK_END");  
          82.                         Looper.myLooper().quit();  
          83.                         // 做完之后报告信息给主线程  
          84.                         mainHandler.sendEmptyMessage(TASK_END_OVER);  
          85.                         Looper.myLooper().quit();  
          86.                         break;  
          87.                     }  
          88.                     super.handleMessage(msg);  
          89.                 }  
          90.             };  
          91.               
          92.             Looper.loop();  
          93.         }  
          94.           
          95.         public void sendMessageTodoYourWork() {  
          96.             Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" +  
          97.                 "Send TASK_START to handler.");  
          98.             // 启动任务(消息只有标识,立即投递)  
          99.             workHandler.sendEmptyMessage(TASK_BEGIN);  
          100.   
          101.             Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" +  
          102.                 "Send TASK_1 to handler.");  
          103.             // 开始任务1(在workHandler的消息队列中获取一个Message对象,避免重复构造)  
          104.             Message msg1 = workHandler.obtainMessage(TASK_1);  
          105.             msg1.obj = "This is task1";  
          106.             workHandler.sendMessage(msg1);  
          107.               
          108.             Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" +  
          109.                 "Send TASK_2 to handler.");           
          110.             // 开启任务2(和上面类似)  
          111.             Message msg2 = Message.obtain();  
          112.             msg2.arg1 = 10;  
          113.             msg2.arg2 = 20;  
          114.             msg2.what = TASK_2;  
          115.             workHandler.sendMessage(msg2);  
          116.   
          117.             Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" +  
          118.                 "Send TASK_END to handler.");  
          119.             // 结束任务(空消息体,延时2s投递)  
          120.             workHandler.sendEmptyMessageDelayed(TASK_END, 2000);  
          121.         }  
          122.     }  

zz android 中的handler

标签:

原文地址:http://www.cnblogs.com/liangouyang/p/5422132.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!