Android高級應用之Handler(一)

問題:如何實現每隔5s鍾更新一下標題。

學過Java多線程的同學,肯定會想,這還不簡單!於是乎有了以下的代碼:

 

public class MainActivity extends Activity {
	private int count = 1;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		new Thread(new TitleThread()).start();

	}

	class TitleThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				setTitle("Welcome to my blog" + count++);
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}


趕緊興致勃勃的運行,可是運行時會報錯:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

這個錯誤究竟是什麼東東?

翻譯過來的意思是:只有原始創建這個視圖層次(view hierachy)的線程才能修改它的視圖(view)。也就是說必須在一般必須在程序的主線程(也就是ui)線程中進行更新界面顯示的工作。

http://jackxlee.blog.51cto.com/2493058/686161 這篇文章有詳細的說明

總結一下:試圖在自定義的線程中更新視圖(如本例我們是不斷的刷新標題)是無法做到的,Android引入了Handler這個特殊類,它架起了Runnable和Activity之間的橋樑。

Handler

在線程的run方法裏發送Message,而在Handler裏,根據不同的Message執行不同的任務。

public class MainActivity extends Activity {
	private int count = 1;
    private Handler handler=new Handler(){
    	public void handleMessage(android.os.Message msg) {
    		switch (msg.what) {
			case 1:
				updateTitle();
				break;

			default:
				break;
			}
    	}
    };
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		new Thread(new TitleThread()).start();
	}

	
	protected void updateTitle() {
		setTitle("Welcome to my blog" + count++);
	}


	class TitleThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				Message message=new Message();//創建一條消息
				message.what=1;//編碼指定
				handler.sendMessage(message);
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}


對於線程的創建也可以採用Timer這個類結合TimerTask來實現

public class TimerActivity extends Activity {
	private int count = 1;
    private Handler handler=new Handler(){
    	public void handleMessage(android.os.Message msg) {
    		switch (msg.what) {
			case 1:
				updateTitle();
				break;

			default:
				break;
			}
    	}
    };
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Timer timer=new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			
			@Override
			public void run() {
				Message message=new Message();
				message.what=1;
				handler.sendMessage(message);
			}
		}, 1000,5000);
	}

	
	protected void updateTitle() {
		setTitle("Welcome to my blog" + count++);
	}
}


 

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