Android入門開發系列學習之 Handler使用

    Android提供瞭一個異步的消息回調機制Handler,  它負責發送消息和處理線程消息隊列中的消息及runnable對象

   Handler實例都是與一個線程和該線程的消息隊列一起使用,一旦創建瞭一個新的handler實例,系統就把該實例與一個線程和該線程的消息隊列捆綁起來,這將可以發送消息和runnable對象給該消息隊列,並在消息隊列出口處處理它們。

     Handler默認使用當前的線程RunLoop,  但是也可以通過它的構造函數來指定某個線程的runloop, 或者使用專用的HandlerThread。

    必須要註意的是, 使用Handler的線程中,必須實現瞭Runloop消息循環,否則會產生運行異常。

    通常情況下,如果我們在主線程使用Handler, 則不需要我們主動去創建runloop, 因為android系統為自動為activity主線程創建一個runloop。

    同樣我們可以在一個特殊的子線程中使用Handler,而不必去創建runloop。這個特殊子線程就是HandlerThread, 查看其源碼,我們可以發現,它也在run方法中實現瞭runloop。

 

 

  下面就介紹Handler的幾種使用場景和用法:

 1. 在主線程中使用Handler

      主線程中使用Handler相對簡單, 下面的示例代碼實現瞭在主線程中創建Handler對象,啟動一個runable方法去刷新進度條。代碼如下:

[java]
//在主線程中創建一個Handler對象 

          //在主線程中創建一個Handler對象[java] view plaincopyprint?                                  Handler  handler = new Handler() 

    public void handleMessage(Message msg) 
    { 
        firBar.setProgress(msg.arg1); 
        handler.post(updateThread); 
         
        Log.v("thread—-", Thread.currentThread().getName()); 
    } 
}; 

                                       Handler  handler = new Handler()
     {
      public void handleMessage(Message msg)
      {
       firBar.setProgress(msg.arg1);
       handler.post(updateThread);
       
       Log.v("thread—-", Thread.currentThread().getName());
      }
     };[java] view plaincopyprint?<SPAN style="WHITE-SPACE: pre">                 handler.post(updateThread);</SPAN>  //去運行 

     handler.post(updateThread);  //去運行
[java]
//創建一個runable去刷新進度條 

        //創建一個runable去刷新進度條[java] view plaincopyprint?              Runnable updateThread = new Runnable() { 
     
    @Override 
    public void run() { 
        // TODO Auto-generated method stub  
        if ( i>= 100) { 
            handler.removeCallbacks(updateThread); 
            return; 
        } 
             
 
         
        i += 10; 
         
        Message msg = handler.obtainMessage(); 
        msg.arg1 = i; 
         
        try { 
            Thread.sleep(1000);    //線程暫停1s  
        } catch (InterruptedException e) { 
            // TODO: handle exception  
            e.printStackTrace(); 
        } 
         
        handler.sendMessage(msg); 
        handler1.sendEmptyMessage(0); 
         
    } 
}; 

               Runnable updateThread = new Runnable() {
  
  @Override
  public void run() {
   // TODO Auto-generated method stub
   if ( i>= 100) {
    handler.removeCallbacks(updateThread);
    return;
   }
    

   
   i += 10;
   
   Message msg = handler.obtainMessage();
   msg.arg1 = i;
   
   try {
    Thread.sleep(1000);    //線程暫停1s
   } catch (InterruptedException e) {
    // TODO: handle exception
    e.printStackTrace();
   }
   
   handler.sendMessage(msg);
   handler1.sendEmptyMessage(0);
   
  }
 };

 

2.  在普通的子線程中使用Handler

     示例代碼如下:

[java]
//創建一個子線程,在其中使用Handler  
class MyThread extends Thread 

     
        public void run() { 
            Looper.prepare(); 
             handler1 = new Handler()//Looper.getMainLooper()  
            { 
                public void handleMessage(Message msg) 
                { 
                    Log.v("SubThread",Thread.currentThread().getName()); 
                     
                    // 這裡執行耗時操作,不會影響到UI主線程  
                    for (int i = 0; i < 1000000000; i++) { 
                         
                    } 
                } 
                 
            }; 
             
            Looper.loop(); 
        } 
 

 //創建一個子線程,在其中使用Handler
 class MyThread extends Thread
 {
  
   public void run() {
    Looper.prepare();
     handler1 = new Handler()//Looper.getMainLooper()
    {
        public void handleMessage(Message msg)
        {
         Log.v("SubThread",Thread.currentThread().getName());
         
         // 這裡執行耗時操作,不會影響到UI主線程
         for (int i = 0; i < 1000000000; i++) {
       
      }
        }
     
    };
    
    Looper.loop();
   }
 
 }

 

3.  在HandlerThread線程中使用Handler

    

[java]
HandlerThread handlerThread = new HandlerThread("handlerThread"); 
handlerThread.start(); 
 
//這裡獲取到HandlerThread的runloop  
MyHandler myHandler = new MyHandler(handlerThread.getLooper()); 

    HandlerThread handlerThread = new HandlerThread("handlerThread");
    handlerThread.start();
    
    //這裡獲取到HandlerThread的runloop
    MyHandler myHandler = new MyHandler(handlerThread.getLooper());

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。