worker thread
最近學到handler,遇到thread的觀念不是很了,就想說先放下handler,回來學習thread。
之前在thread提到,如果只有單一thread的模式,可能因為運行網路存取或資料庫查詢等而阻塞UI thread,使應用程式看起來很不好用。為了避免此問題,應該將需要花較多時間的工作,丟到另一個thread("background" or "worker "thread)執行。
舉個例子,以下的程式碼是一個點擊程式,當點擊後,在另一thread中執行下載圖片的工作,並顯示出來。
public void onClick(View v) { new Thread(new Runnable() { public void run() { Bitmap b = loadImageFromNetwork("http://example.com/image.png"); mImageView.setImageBitmap(b); } }).start(); }
首先,程式碼似乎沒有甚麼問題,因為產生一個新的thread來處理下載文件的工作。然而它違反了第二條單一執行續模式的原則:do not access the Android UI toolkit from outside the UI thread,此例子從worker thread修改了ImageView,取代從UI thread修改。如此可能造成無法定義無法預期的行為,到時要追蹤就會變得困難與費時。
如何解決這樣的問題,android提供許多方法可以從其他的thread存取UI thread,以下列表顯示所有方法。
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- View.postDelayed(Runnable , long)
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
現在這樣運行就是thread-safe了:網路下載圖片的工作在另一個htread執行,ImageView在UI thread中操縱。
然而,隨功能增加,程式也越複雜,這樣的程式變得複雜以及困難去維護。為了管理與worker thread越來越多的互動,你也許可以考慮使用Handler,處理來自UI thread的訊息。也許最好的方法是繼承AsyncTask類別,它可以簡化worker thread需要與UI thread的任務。
沒有留言:
張貼留言