網頁

2010年6月23日 星期三

關於介面與執行序Only the original thread that created a view hierarchy can touch its views.

Android 是一個多功多執行的作業系統,雖然可以多執行緒
但是遵循著mvc模式 ,所以當非UI的執行序,嘗試去改變ui介面的程式就會出現錯誤而關閉程式
例如

寫了一個遊戲,遊戲的核心是一個執行緒,定期需要計算遊戲的內容,且需要定時的更新畫面,然而跟跟新畫面,需要呼叫 invalidate 這個方法,偏偏這個方法使會變更介面,所以android只好把你強迫關閉程式。告訴你Only the original thread that created a view hierarchy can touch its views

最簡單的方法就是不要使用 invalidate 改用 postInvalidate();

但只是剛好invalidate 有 postInvalidate(); 可以幫助更新畫面,但是如果要更變tTextBox內容,或是 setContentView(view); 那可就沒那麼幸運了。

事實上這樣龜毛的規則並不是Android訂製的,c#的開發使用者也是有著相同的困腦,
但在c# 會使用委派來將 要改變介面的事情 透過委派 交給 UI的執行序去執行。

然而在Android 使用了比較值覺得寫法
runOnUiThread(new Runnable(){
public void run() {
//要改變介面的程式寫在這裡
}});

這樣android就會裡面的程式碼,改由ui的執行序來執行,而不會出錯了,
所以類推本來寫postInvalidate(); 可以改寫成

runOnUiThread(new Runnable(){
public void run() {
invalidate
}});



通常錯誤如下:
06-23 15:47:40.123: ERROR/AndroidRuntime(393): Uncaught handler: thread Thread-10 exiting due to uncaught exception
06-23 15:47:40.135: ERROR/AndroidRuntime(393): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

沒有留言: