Re: [問題] handeler VS method 改UI thread的差異?

作者: kuangjc5566 (匡匡56)   2018-01-20 02:13:04
※ 引述《ntuleo (里歐)》之銘言:
: 我們都知道要開一個thread去改UI的話是不行的,需要用handler機制把thread用
: sendmessage的方式回call main thread的handle message才能修改
: 這邊有個疑問是
: 這樣跟直接用method在main thread中修改UI有什麼差異呢?
: 因為用handler新開的thread雖然是在後台跑
: 但是回call回來還是block住main thread不是嗎? 這樣跟用method有什麼不同呢?
不錯不錯。
你有在思考為什麼Android Framework不允許你在main thread之外的thread操作UI。
很多人其實搞不清楚這是怎麼一回事,
所以就會有一些倒因為果的回答,比如說ANR或阻塞之類的。
就好像你問人為什麼要吃東西,大家都回答因為肚子餓啊之類的回答。
這算是答案嗎?
若是單純要說有回答,是的,是有回答。
但這回答有意義嗎?
不過這是典型台灣教育的人會出現的想當然爾。唉…
好的,繼續回答標題問的這個問題。
現代的UI Framework通常會設計為操作UI只能在某一個特定的thread,我們通常會叫它UI thread。這裡要釐清一下,我在這裡說的UI thread和main thread語意上不一定是同一個thread。
WTF?
因為我指的不僅僅是Android Framework,而是指現代的UI Framework設計。只是Android Framework讓main thread 成了UI thread。所以只寫過Android的人會以為在其他系統上,main thread 就是UI thread。不是!是Android選擇了這樣的設計。你要我舉main thread不是UI thread的Framewor。OK,Java標準的UI Framework,叫swing,main thread就不是UI thread。
釐清了這個觀念後,接下來的問題是,為什麼現代的系統都要設計UI只能跑在單一thread上?不能讓很多個thread都操縱UI嗎?
不行。因為不這樣設計會容易 deadlock。
為什麼?
這要分兩方面講。
第一個概念,
如果有兩個thread寫程式時上鎖的順序,
thread 1是 拿到Lock A再來是 拿Lock B。
而thread 2 是 拿到Lock B 再來是拿 Lock A。
這樣有可能thread 1 拿到Lock A,
這時thread 2拿到Lock B。
完蛋了,情況變成是thread 1永遠拿不到Lock B,
thread 2永遠拿不到Lock A,產生了deadlock。
也就是多執行緒程式很重要的一條,
不同執行緒上鎖的順序要一致。
第二個概念
我們電腦系統的UI運作可以大概這樣分層
App 應用程式
UI Framework 框架
OS 作業系統
HW 硬體
你寫程式更改UI時程式是從APP>>UI Framework>> OS >> HW
而你寫某個UI元件被觸摸到時的反應是
HW>>OS>>UI Framework>>APP
嗯,兩者方向相反。
好了今天要是這兩者跑在不同thread上,而程式要取得某兩個lock,lock A,lock B。
可能會有這樣子的情況你寫程式更改UI時程式是從
APP>>UI Framework part 1>>拿lock A>>UI Framework part 2>>拿lock B>>UI Framework part 3>>OS >> HW
而按鈕觸發實的反應執行時是
HW>>OS >>UI Framework part a >>拿lock B >>UI Framework part b>>拿lock A>>UI Framework part c>>APP
剛好滿足了deadlock的條件
這就是為什麼UI要限制在單ㄧthread ,我們通常稱呼為UI thread上執行。
你又會問那要是UI Framework設計為多執行緒會如何?
嗯,那你要很聰明,又很小心,很了解UI內部運作的細節來避開死鎖。
但是要是死鎖會很難偵錯,因為死鎖有時會發生有時不會發生。
而以前有人這樣設計系統的情況是,沒人讀UI Framework設計者的說明檔案和提醒,寫程式的人遇到死鎖時只是罵UI Framework設計的人是白癡,設計很爛。所以設計UI Framework現在都流行把UI限制在專門的thread上跑。
大概4醬。
讀到這個問題很久了,只是我很懶得回答,因為要寫這麼多。而且我當下還是只用手機寫,兩年了,我終於斷斷續續寫完了。
這篇文章送給認真思考這個問題的你。
作者: cha122977 (CHA)   2018-01-20 02:30:00
另外UI視情況會故意掉禎 也不適合一般的function call
作者: kuangjc5566 (匡匡56)   2018-01-20 02:56:00
我不懂function call和UI thread有什麼關系?function call一定會執行到,不是寫在Listener裡就不一定會執行,掉frame是別的層面的機制吧?
作者: lnmlee   2018-01-20 22:51:00
就跟軍艦的武器官 統一掌管武器發射概念一樣
作者: y3k (激流を制するは静水)   2018-01-21 01:04:00
UI Thread九成九是同一個避免畫面撕裂或當機之類的事這是我自己的理解 至於dead lock這問題真沒想過XD
作者: ininmm (子虛烏有)   2018-01-21 02:17:00
受教了 自己還沒有從這個角度思考過

Links booklink

Contact Us: admin [ a t ] ucptt.com