Android 中的Handler
Handler在Android中是一個輕量級的線程,主要接受子線程發送的資料, 並用此資料配合主線程更新UI. 它有兩個作用: (1): 安排訊息或Runnable 在某個主線程中某個地方執行, (2)安排一個動作在不同的線程中執行。
當應用程式啟動時,Android首先會開啟一個主線程 (也就是UI線程) , 主線程為管理介面中的UI控制項,進行事件分發, 比如說, 你要是點擊一個 Button, Android會分發事件到Button上,來響應你的操作。 如果此時需要一個耗時的操作,例如: 連網讀取資料,或者讀取本地較大的一個檔案的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,介面會出現ANR, 如果超過5秒鐘還沒有完成的話,會收到Android系統的一個錯誤提 "強制關閉". 這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程不會涉及到UI更新,也就是說,更新UI只能在主線程中更新,子線程中操作是危險的. 這個時候,Handler就出現了來解決這個複雜的問題,由於Handler運行在主線程中(UI線程中),它與子線程可以通過Message對象來傳遞資料,這個時候,Handler就承擔著接受子線程傳過來的(子線程用sedMessage()方法傳弟)Message對象,(裡麵包含資料) , 把這些訊息放入主線程隊列中,配合主線程進行更新UI。
來看一個執行個體,在子線程中與網路進行互動,然後在UI上更新server返回的資料。
package com.smarthouse.handler;import com.smarthouse.activity.MainActivity;import com.smarthouse.activity.R;import com.smarthouse.thread.DoorThread;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;/** * 處理Door 事件請求並更新對應的主UI線程 * @author liyangchao * */public class DoorHanlder extends Handler{private static final String TAG = DoorHanlder.class.getSimpleName();private MainActivity mainActivity;private DoorThread doorThread;public DoorHanlder() {// TODO Auto-generated constructor stub}public DoorHanlder(Looper L) {super(L);}public DoorHanlder(MainActivity mainActivity) {super();this.mainActivity = mainActivity;doorThread = new DoorThread(mainActivity);doorThread.start();}@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubLog.d(TAG, "DoorHandler starting handler message.....");super.handleMessage(msg);//更新UIBundle bundle = msg.getData();String door_detail = bundle.getString("door") ;mainActivity.UpdateDoorDetails(door_detail);}}
在看這個Handler對應的Thread的代碼
package com.smarthouse.thread;import android.os.Bundle;import android.os.Message;import android.util.Log;import com.smarthouse.activity.MainActivity;import com.smarthouse.dealer.DealRequest;public class DoorThread extends Thread{private static final String TAG = DoorThread.class.getSimpleName();private MainActivity mainActivity;//private CountDownLatch countDownLatch;private String result = null;public DoorThread(MainActivity mainActivity) {this.mainActivity = mainActivity;//countDownLatch = new CountDownLatch(1);}@Overridepublic void run() {try {Thread.sleep(1000);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();} Log.d(TAG, "doorThread starting......."); DealRequest dealRequest = new DealRequest(); result = dealRequest.GetContentFromUrl("http://www.reveriedream.com/test/appget3.asp"); Message msg = new Message(); Bundle bundle = new Bundle();//存放資料 bundle.putString("door", result); msg.setData(bundle); mainActivity.getDoorHanlder().sendMessage(msg);}}
OK,現在去主線程中調用它,只需要一句話;
doorHanlder = new DoorHanlder(this);