什麼是Handler

 

 
handler通俗講就是在各個進程之間發送數據的處理對象。在任何進程中,只要得到了另外一個進程的handler則能夠經過 handler.sendMessage(message)方法向那個進程發送數據。基於這個機制,咱們在處理多線程的時候能夠新建一個thread,這 個thread擁有UI線程中的一個handler。當thread處理完一些耗時的操做後經過傳遞過來的handler向UI線程發送數據,由UI線程去更新界面。
 
Handler類簡介
 
在Android平臺中,新啓動的線程是沒法訪問Activity裏的Widget的,固然也不能將運行狀態外送出來,這就須要有Handler機 制進行消息的傳遞了,Handler類位於android.os包下,主要的功能是完成Activity的Widget與應用程序中線程之間的交互。接下 來對該類中經常使用的方法進行介紹,以下表所示。
 
 Handler類的經常使用方法
  android

 


方法簽名
  多線程

描     述
  app

 

public void handleMessage (Message msg)
  eclipse

子類對象經過該方法接收信息
  ide

 

public final boolean sendEmptyMessage (int what)
  函數

發送一個只含有 what 值的消息
  oop

 

public final boolean sendMessage (Message msg)
  post

發送消息到 Handler ,
 
經過 handleMessage 方法接收
  this

 

public final boolean hasMessages (int what)
  線程

監測消息隊列中是否還
 
有 what 值的消息
 

 

public final boolean post (Runnable r)
 

將一個線程添加到消息隊列
 

    開發帶有Handler類的程序步驟以下。   在Activity或Activity的Widget中開發Handler類的對象,並重寫handleMessage方法。   在新啓動的線程中調用sendEmptyMessage或者sendMessage方法向Handler發送消息。   Handler類的對象用handleMessage方法接收消息,而後根據消息的不一樣執行不一樣的操做。       在Android 中Handler和Message、Thread有着很密切的關係。Handler 主要是負責Message的分發和處理。可是這個Message從哪裏來的呢?Message 由一個消息隊列進行管理,而消息隊列卻由一個Looper進行管理。Android系統中Looper負責管理線程的消息隊列和消息循環,具體實現請參考Looper的源碼。 能夠經過Loop.myLooper()獲得當前線程的Looper對象,經過Loop.getMainLooper()能夠得到當前進程的主線程的 Looper對象。Android系統的消息隊列和消息循環都是針對具體線程的,一個線程能夠存在(固然也能夠不存在)一個消息隊列和一個消 息循環(Looper),特定線程的消息只能分發給本線程,不能進行跨線程,跨進程通信。可是建立的工做線程默認是沒有消息循環和消息隊列的,若是想讓該 線程具備消息隊列和消息循環,須要在線程中首先調用Looper.prepare()來建立消息隊列,而後調用Looper.loop()進入消息循環。   雖然說 特定線程的消息只能分發給本線程,不能進行跨線程通信,可是因爲能夠經過得到線程的Looper對象來進行曲線的實現不一樣線程間消息的傳遞,代碼以下   package com.mytest.handlertest;  import android.app.Activity;  import android.graphics.Color;  import android.os.Bundle;  import android.os.Handler;  import android.os.Looper;  import android.os.Message;  import android.util.Log;  import android.view.View;  import android.view.View.OnClickListener;  import android.view.ViewGroup.LayoutParams;  import android.widget.Button;  import android.widget.LinearLayout;  import android.widget.TextView;  public class HandlerTest extends Activity implements OnClickListener{            private String TAG = "HandlerTest";      private boolean bpostRunnable = false;            private NoLooperThread noLooperThread = null;        private OwnLooperThread ownLooperThread = null;        private ReceiveMessageThread receiveMessageThread =null;            private Handler  mOtherThreadHandler=null;      private EventHandler mHandler = null;             private Button btn1 = null;      private Button btn2 = null;      private Button btn3 = null;      private Button btn4 = null;      private Button btn5 = null;      private Button btn6 = null;      private TextView tv = null;      /** Called when the activity is first created. */      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);                   LinearLayout layout = new LinearLayout(this);          LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(250, 50);          layout.setOrientation(LinearLayout.VERTICAL);                    btn1 = new Button(this);          btn1.setId(101);          btn1.setText("message from main thread self");          btn1.setOnClickListener(this);          layout.addView(btn1, params);                    btn2 = new Button(this);          btn2.setId(102);          btn2.setText("message from other thread to main thread");          btn2.setOnClickListener(this);          layout.addView(btn2,params);                    btn3 = new Button(this);          btn3.setId(103);          btn3.setText("message to other thread from itself");          btn3.setOnClickListener(this);          layout.addView(btn3, params);                    btn4 = new Button(this);          btn4.setId(104);          btn4.setText("message with Runnable as callback from other thread to main thread");          btn4.setOnClickListener(this);          layout.addView(btn4, params);                    btn5 = new Button(this);          btn5.setId(105);          btn5.setText("main thread's message to other thread");          btn5.setOnClickListener(this);          layout.addView(btn5, params);                    btn6 = new Button(this);          btn6.setId(106);          btn6.setText("exit");          btn6.setOnClickListener(this);          layout.addView(btn6, params);                    tv = new TextView(this);          tv.setTextColor(Color.WHITE);          tv.setText("");          params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);          params.topMargin=10;          layout.addView(tv, params);                    setContentView(layout);                    receiveMessageThread = new ReceiveMessageThread();          receiveMessageThread.start();                }            class EventHandler extends Handler{                    public EventHandler(Looper looper){              super(looper);          }                    public EventHandler(){              super();          }          @Override          public void handleMessage(Message msg) {              // TODO Auto-generated method stub              super.handleMessage(msg);              Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId());              switch(msg.what){              case 1:                  tv.setText((String)msg.obj);                  break;                                case 2:                  tv.setText((String)msg.obj);                  noLooperThread.stop();                  break;                                case 3:                  //不能在非主線程的線程裏面更新UI,因此這裏經過log打印信息                  Log.e(TAG,(String)msg.obj);                  ownLooperThread.stop();                  break;              default:                  Log.e(TAG,(String)msg.obj);                  break;              }          }                }              //ReceiveMessageThread has his own message queue by execute Looper.prepare();       class ReceiveMessageThread extends Thread {                    @Override          public void run(){              Looper.prepare();              mOtherThreadHandler= new Handler(){                  @Override                  public void handleMessage(Message msg) {                      // TODO Auto-generated method stub                      super.handleMessage(msg);                                            Log.e(TAG,"-------+>"+(String)msg.obj);                      Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId());                                        }                                  };               Log.e(TAG, "ReceiveMessageThread id:--------+>" + this.getId());                Looper.loop();          }      }            class NoLooperThread extends Thread {          private EventHandler mNoLooperThreadHandler;          @Override          public void run() {                            Looper myLooper = Looper.myLooper();              Looper mainLooper= Looper.getMainLooper();                            String msgobj;              if(null == myLooper){                  //這裏得到的是主線程的Looper,因爲NoLooperThread沒有本身的looper因此這裏確定會被執行                  mNoLooperThreadHandler = new EventHandler(mainLooper);                  msgobj = "NoLooperThread has no looper and handleMessage function executed in main thread!";               } else{                  mNoLooperThreadHandler = new EventHandler(myLooper);                  msgobj = "This is from NoLooperThread self and handleMessage function executed in NoLooperThread!";               }                            mNoLooperThreadHandler.removeMessages(0);                            if(bpostRunnable == false){              //send message to main thread                  Message msg = mNoLooperThreadHandler.obtainMessage(2, 1, 1, msgobj);                  mNoLooperThreadHandler.sendMessage(msg);                  Log.e(TAG, "NoLooperThread id:--------+>" + this.getId());               }else{                  //下面new出來的實現了Runnable接口的對象中run函數是在Main Thread中執行,不是在NoLooperThread中執行 記得 null == myLooper麼                  //注意Runnable是一個接口,它裏面的run函數被執行時不會再新建一個線程                    //您能夠在run上加斷點而後在eclipse調試中看它在哪一個線程中執行                                      mNoLooperThreadHandler.post(new Runnable(){                      public void run() {                          // TODO Auto-generated method stub                          tv.setText("update UI through handler post runnalbe mechanism!");                            Log.e(TAG, "update UI id:--------+>" + Thread.currentThread().getId());                           noLooperThread.stop();                        }                                        });              }          }                }            class OwnLooperThread extends Thread{          private EventHandler mOwnLooperThreadHandler = null;                    @Override          public void run() {              Looper.prepare();              Looper myLooper = Looper.myLooper();              Looper mainLooper= Looper.getMainLooper();                            String msgobj;                            if(null == myLooper){                  mOwnLooperThreadHandler = new EventHandler(mainLooper);                  msgobj = "OwnLooperThread has no looper and handleMessage function executed in main thread!";               }else{                  mOwnLooperThreadHandler = new EventHandler(myLooper);                  msgobj = "This is from OwnLooperThread self and handleMessage function executed in NoLooperThread!";              }                            mOwnLooperThreadHandler.removeMessages(0);                            //給本身發送消息              Message msg = mOwnLooperThreadHandler.obtainMessage(3,1,1,msgobj);              mOwnLooperThreadHandler.sendMessage(msg);              Looper.loop();          }      }            public void onClick(View v) {          // TODO Auto-generated method stub          switch(v.getId()){          case 101:              //主線程發送消息給本身              Looper looper = Looper.myLooper();//get the Main looper related with the main thread               //若是不給任何參數的話會用當前線程對應的Looper(這裏就是Main Looper)爲Handler裏面的成員mLooper賦值              mHandler = new EventHandler(looper);              // 清除整個MessageQueue裏的消息                mHandler.removeMessages(0);              String obj = "This main thread's message and received by itself!";                            Message msg = mHandler.obtainMessage(1,1,1,obj);              // 將Message對象送入到main thread的MessageQueue裏面               mHandler.sendMessage(msg);              break;          case 102:              //other線程發送消息給主線程              bpostRunnable = false;              noLooperThread = new NoLooperThread();                noLooperThread.start();                break;          case 103:               //other thread獲取它本身發送的消息                tv.setText("please look at the error level log for other thread received message");                ownLooperThread = new OwnLooperThread();                ownLooperThread.start();                break;            case 104:                    //other thread經過Post Runnable方式發送消息給主線程                bpostRunnable = true;                noLooperThread = new NoLooperThread();                noLooperThread.start();                break;          case 105:              //主線程發送消息給other thread                if(null!=mOtherThreadHandler){                tv.setText("please look at the error level log for other thread received message from main thread");                String msgObj = "message from mainThread";                Message mainThreadMsg = mOtherThreadHandler.obtainMessage(1, 1, 1, msgObj);                mOtherThreadHandler.sendMessage(mainThreadMsg);                }                break;            case 106:                finish();                break;            }      }  } 

相關文章
相關標籤/搜索