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

作者: ntuleo (里歐)   2015-03-20 16:59:27
我們都知道要開一個thread去改UI的話是不行的,需要用handler機制把thread用
sendmessage的方式回call main thread的handle message才能修改
這邊有個疑問是
這樣跟直接用method在main thread中修改UI有什麼差異呢?
因為用handler新開的thread雖然是在後台跑
但是回call回來還是block住main thread不是嗎? 這樣跟用method有什麼不同呢?
作者: hellogg1 (安卓嫩嫩工程師)   2015-03-20 17:07:00
所以你不能在main thread做耗時的事情否則會ANR
作者: issuemylove (NotLove)   2015-03-20 17:28:00
UI的修改前,可能會有大量的計算 大量計算跑在main下略 你懂的
作者: ntuleo (里歐)   2015-03-20 19:42:00
大量計算開thread,修改UI再call method這樣不使用handler也可以達到handler改UI的效果不是嗎?不了解的點是兩種方法都會block main thread,那為什麼需要用比較麻煩的handler呢?
作者: sdyy (中壢市的小智)   2015-03-20 20:32:00
怎麼會一樣 例如你要載入一張網路圖片 把圖片載好花1秒用main thread跑 你這一秒都被卡住 而另開thread 則只要指定載好的圖片 記憶體都已擺好也就不會block到其他UI畫面
作者: corrupt003 (QQ)   2015-03-20 20:43:00
call method 在thread 底下做的話,還是跑在thread阿會用handler是因為一般情形下handler是綁ui thread
作者: ssccg (23)   2015-03-20 20:48:00
call回來是在main thread的message queue上排程,不會直接block main thread,會block就是你用錯了handler是把message queue包裝起來用,跟開thread是兩回事
作者: corrupt003 (QQ)   2015-03-20 20:51:00
所以有複雜計算在thread做,做完需要改ui時用handler,handler裡 call method才會在 ui thread 更新ui
作者: ssccg (23)   2015-03-20 20:52:00
你看起來跟thread不太熟,直接call method是在同一個thread
作者: ntuleo (里歐)   2015-03-20 21:57:00
感謝大家,我目前的理解是這樣的handler誕生的主要原因是主線程要和子線程溝通用的一般thread做不到這一點所以比較heavy的工作放在thread做,要改ui再用handler通知main thread修改但今天如果只是簡單的setText,那其實直接call就可以了開thread再用handler call和直接call在這是沒有區別的因為中間沒有複雜的運算
作者: qweqweqweqwe (4qwe)   2015-03-20 22:00:00
是阿.. 所以這種就直接setText 就可以了阿..
作者: ssccg (23)   2015-03-20 22:26:00
有什麼不同你試一下就知道,只有在main thread才可以改UI直接call你會得到一個CalledFromWrongThreadException
作者: ckvir (ckvir)   2015-03-22 03:10:00
回call回來又不會block住
作者: KeySabre (KeySabreur)   2015-03-23 18:08:00
main thread已經很忙,要更新UI,又要處理touch event、key event等,如果用來處理其他事情,使得畫面無法即時更新,觸控事件無法即時處理,操作就會卡頓,人眼認為fps 30是順暢;另外我記得系統每16ms會draw一次,阻礙到就會感覺不順暢。Android有ANR機制保護,可讓使用者強制關閉程序,避免main thread被惡意佔用使得手機被綁架。另外broadcast receiver, service等也要注意,他們在系統內也有對應的回應時間控制。Handler是Android提供讓你做非同步調用的機制所含的一個類別,大致上就是你可以開一個thread然後放Looper.prepare(),Looper會給這個thread一個message queue並且用迴圈去取,Handler必須與Looper搭配,當有message時就會發到Handler的handleMessage()。Handler的無參數建構子會用當前thread的looper,所以你在main thread創handler,就能利用main thread本來就有的looper,當你從其他thread發送訊息給這個handler時,最終就可以在main thread處理這個訊息。如果要給別的thread一個handler,用法前面說過了,不然也可直接利用HandlerThread這個類別。

Links booklink

Contact Us: admin [ a t ] ucptt.com