2011-10-09 62 views
2

我知道沒有線程可以訪問當前視圖,除非它是UI線程。我想知道爲什麼?爲什麼哪個線程正在改變視圖?這是安全原因嗎?這是圍繞我用的工作:爲什麼不能使用UI線程訪問視圖的線程?

 public void doLayout() 
     { 
      Runnable run = new Runnable() 
      { 
       public void run() 
       { 
        ViewerActivity.setContentView(R.layout.main); 
       } 
      }; 

      handler.post(run); 
     } 

     private Handler handler;' 

這是一種痛苦要做到這一點,每次我想改變佈局。有沒有不同的工作?我知道異步任務,我從來沒有找到一個好的方法來使用它,比我在做什麼好?所有相關的答案都很有趣!

+4

你應該閱讀更多關於Java中鎖定/同步(即當使用「同步」) - 一旦你明白,這將是顯而易見的,爲什麼你有爲了赴湯蹈火從單獨的線程與UI線程進行交互。 –

+0

分離的原因是爲了避免死鎖。假設你可以自由修改任何線程的視圖。假設你正在進行數據庫調用。所以,你得到一個視圖組件的處理程序,然後查詢數據庫,但數據庫鎖定並隨後鎖定當前線程。現在UI線程也將被鎖定,因爲您正在修改視圖,並且必須等待它被釋放才能安全繼續。這會產生非常糟糕的程序,最終會導致比目前更多的鎖定。 – methodin

+0

大多數用戶界面,無論平臺和語言如何,都只能訪問主用戶界面線程中的用戶界面,推理通常是,製作線程安全用戶界面非常困難,不值得花費精力,而且會導致非常嚴重的速度損失因爲圖形用戶界面環境需要快速響應。 – nos

回答

12

是的你的權利:爲了安全起見,你不能在另一個線程上修改視圖(這就是爲什麼叫做UI線程)。它可以防止您將UI數據置於不一致的狀態,這可能會導致應用程序崩潰,並且很難進行調試。所以android的API只是禁止(這是一個好主意)。這是您可以在大多數API中找到的常見UI模式。

就可以更新post()runOnUiThread()任何觀點:

anyView.post(new Runnable() { 
    public void run() { 
     // do update here 
    } 
}); 

爲什麼這種模式?
同步不是免費的。它影響性能。因此,在同一個線程上更改UI更容易。

如果我可以修改不同線程的數據會發生什麼?
例如:線程A正在改變視圖的顏色和線程B正在讀取同一時刻的顏色。由於多線程不能保證首先執行哪條指令,因此可能會得到意想不到的結果。顏色爲黑色(0|0|0)之前,線程A要設置白色(255|255|255),並開始將紅色組件設置爲255,線程B開始讀取並獲取整個顏色,然後線程A有機會完成並獲得顏色紅色(255|0|0)代替黑色。

這是一個簡單的例子,這將影響視覺效果,但如果這種情況發生了一些非常重要的數據應用程序會崩潰可怕和這樣的錯誤是如此骯髒和難以調試。有很多要了解多線程,也許this java tutorial是一個很好的起點...

1

Android應用程序使用Single Thread Model和此線程負責將各種事件分派到UI元素。有兩個規則,這單線程模型:

  1. 如果你創建一個線程,使用不要阻塞UI線程
  2. 不要從UI線程

外部訪問Android的UI工具包View以外的UI thread則違反了第二條規則。

1

安全性不是唯一的UI線程是唯一可以訪問Views的線程。主要原因是視圖背後的代碼可能不是線程安全的。這意味着如果您有多個線程讀取和寫入通用變量,則不能保證數據不會損壞。

看看這個great wikipedia article about thread safety.

相關問題