使用Handler在子線程中更新UI

一、Handler的定義:
        主要接受子線程發送的數據, 並用此數據配合主線程更新UI.

        解釋: 當應用程序啓動時,Android首先會開啓一個主線程 (也就是UI線程) , 主線程爲管理界面中的UI控件,進行事件分發, 比如說, 你要是點擊一個 Button, Android會分發事件到Button上,來響應你的操作。  如果此時需要一個耗時的操作,例如: 聯網讀取數據,或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現假死現象, 如果5秒鐘還沒有完成的話,會收到Android系統的一個錯誤提示  "強制關閉".  這個時候我們需要把這些耗時的操作,放在一個子線程中,因爲子線程涉及到UI更新,並且Android主線程是線程不安全的(也就是說允許多個子線程去操控它,但正是由於允許多個線程操控,因此容易發生錯誤),爲了避免UI控件發生這樣的錯誤,更新UI只能在主線程中更新。這個時候,Handler就出現了來解決這個複雜的問題,由於Handler運行在主線程中(UI線程中),它與子線程可以通過Message對象來傳遞數據,這個時候,Handler就承擔着接受子線程傳過來的(子線程用sedMessage()方法傳弟)Message對象,(裏面包含數據)  , 把這些消息放入主線程隊列中,配合主線程進行更新UI。說白了,子線程想操作UI,可以,你告訴我(Handler),我來更新。


二、Handler一些特點
        handler可以分發Message對象和Runnable對象到主線程中, 每個Handler實例,都會綁定到創建他的線程中(一般是位於主線程),
        它有兩個作用: (1):  安排消息或Runnable 在某個主線程中某個地方執行, (2)安排一個動作在不同的線程中執行
      
        Handler中分發消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)


        以上post類方法允許你排列一個Runnable對象到主線程隊列中,
        sendMessage類方法, 允許你安排一個帶數據的Message對象到隊列中,等待更新.


三、Handler實例
      子類需要繼承Handler類,並重寫handleMessage(Message msg) 方法, 用於接受線程數據
      以下爲一個實例,它實現的功能爲 : 通過線程修改界面TextView的內容

package com.plusjun.hallo2;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	TextView tv1;
	Button bt1;
	MyHandler myHandler;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		bt1 = (Button)findViewById(R.id.bt1);
		tv1 = (TextView)findViewById(R.id.tv1);
		bt1.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				//new一個Runn類,放入Thread中,並執行
				new Thread(new Runn()).start();
			}
		});
		myHandler = new MyHandler();
		// 當創建一個新的Handler實例時, 它會綁定到當前線程和消息的隊列中,開始分發數據
		// Handler有兩個作用, (1) : 定時執行Message和Runnalbe 對象
		// (2): 讓一個動作,在不同的線程中執行.

		// 它安排消息,用以下方法
		// post(Runnable)
		// postAtTime(Runnable,long)
		// postDelayed(Runnable,long)
		// sendEmptyMessage(int)
		// sendMessage(Message);
		// sendMessageAtTime(Message,long)
		// sendMessageDelayed(Message,long)

		// 以上方法以 post開頭的允許你處理Runnable對象
		//sendMessage()允許你處理Message對象(Message裏可以包含數據,)
	}

	class MyHandler extends Handler{
		// 子類必須重寫此方法,接受數據
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Bundle b = msg.getData();
			String color = b.getString("no1");
			tv1.setText(color);
		}
	}

	class Runn implements Runnable{
		public void run() {
			Message msg = new Message();
			Bundle b = new Bundle();
			b.putString("no1", "更新的字符串");
			msg.setData(b);
			// 向Handler發送消息,更新UI
			MainActivity.this.myHandler.sendMessage(msg);
		}
	}
}


以上部分內容轉載或參考來源如下:
http://www.cnblogs.com/dawei/archive/2011/04/09/2010259.html
在此表示感謝。
轉載請註明來源,版權歸原作者所有,未經同意嚴禁用於任何商業用途。
微博:http://weibo.com/theworldsong
郵箱:[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章