android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...
只要參與過(guò)安卓項(xiàng)目開發(fā)一兩年的朋友們應(yīng)該清楚,為了避免UI渲染出現(xiàn)異常安卓框架限制UI操作只能在主線程中進(jìn)行,如果貿(mào)然在子線程做了UI操作結(jié)果會(huì)怎樣?我們隨便寫下了如下測(cè)試代碼。
不出意外的話,代碼執(zhí)行報(bào)錯(cuò)拋出了名為CalledFromWrongThreadException異常,這件事告訴我們UI操作必須在主線程中進(jìn)行。
那么是不是在所有情況下,子線程都不能做UI操作呢?換句話說(shuō)是不是只要在子線程中操作UI就一定會(huì)拋出上述異常呢?今天我們不妨針對(duì)這個(gè)問題做下研究。
還是以上述代碼為例,我們只在布局中把TextView的layout_width改成match_parent的話,業(yè)務(wù)邏輯什么都不改,再運(yùn)行一下代碼竟然發(fā)現(xiàn)一切運(yùn)行正常。
怎么樣?這種情況你們想到了嗎?看到這里有沒有顛覆自己的世界觀?也就是說(shuō)主線程里不能操作UI這句話并不是完全正確,那么什么情況下不正確呢?通過(guò)上面的例子來(lái)看,至少當(dāng)TextView組件足夠大以至于能容納其內(nèi)容時(shí)上面這句是不正確的,除非你不承認(rèn)修改TextView文本是UI操作。
下面我們?cè)噲D從源碼(Api 28)角度來(lái)分析為什么會(huì)出現(xiàn)上面這種打破了安卓程序員固有思維的現(xiàn)象,我們先討論出異常這種情況。從TextView設(shè)置文本的方法setText的方法調(diào)用棧可知,這個(gè)方法會(huì)調(diào)用View的requestLayout方法,而這個(gè)方法最終又會(huì)調(diào)用ViewRootImpl的checkThread方法,正是在這個(gè)方法里拋出了上述異常。
那么我們將TextView的寬度改成足夠大的時(shí)候,方法的調(diào)用棧又會(huì)發(fā)生什么變化呢?我們?cè)倩氐絋extView的checkForRelayout方法中,在這個(gè)方法的8862行是判斷TextView是否需要根據(jù)文本的內(nèi)容變化來(lái)改變控件的大小。如果控件足夠大的話,requestLayout方法將不會(huì)調(diào)用,所以也不至于去校驗(yàn)布局操作是在哪個(gè)線程處理了。
綜上,子線程是可以處理UI操作的,只要沒涉及到控件布局變化就行,其實(shí)也不僅限于TextView,大家有時(shí)間完全可以嘗試其他控件如ImageView。
不過(guò)雖然在某些情況下可以在子線做UI操作,但是還是不建議那樣做,因?yàn)樵陂_發(fā)過(guò)程中很難去判斷也沒必要去判斷文本內(nèi)容會(huì)不會(huì)超出控件,作為開發(fā)者還是要遵守安卓開發(fā)規(guī)范盡量保證在主線程里操作UI。不過(guò)如果有一天面試的時(shí)候有人問你主線程是否可以做UI操作的話,你應(yīng)該能舉出上面這種情況,這樣面試官一定會(huì)對(duì)你刮目相看。
舉報(bào)/反饋
總結(jié)
以上是生活随笔為你收集整理的android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 京东金条审核失败是什么原因
- 下一篇: python期末大作业_大一期末考试很重