android不能在主線程,安卓開發:主線程真的不能做UI操作嗎?這一點很多程序員都沒想到...

只要參與過安卓項目開發一兩年的朋友們應該清楚,為了避免UI渲染出現異常安卓框架限制UI操作只能在主線程中進行,如果貿然在子線程做了UI操作結果會怎樣?我們隨便寫下了如下測試代碼。

ca981fac72e71ad926b56c4303fcc3aa.png

不出意外的話,代碼執行報錯拋出了名為CalledFromWrongThreadException異常,這件事告訴我們UI操作必須在主線程中進行。

那么是不是在所有情況下,子線程都不能做UI操作呢?換句話說是不是只要在子線程中操作UI就一定會拋出上述異常呢?今天我們不妨針對這個問題做下研究。

還是以上述代碼為例,我們只在布局中把TextView的layout_width改成match_parent的話,業務邏輯什么都不改,再運行一下代碼竟然發現一切運行正常。

836b989afa95b76f334f8c145b288b6c.png

怎么樣?這種情況你們想到了嗎?看到這里有沒有顛覆自己的世界觀?也就是說主線程里不能操作UI這句話并不是完全正確,那么什么情況下不正確呢?通過上面的例子來看,至少當TextView組件足夠大以至于能容納其內容時上面這句是不正確的,除非你不承認修改TextView文本是UI操作。

ced49c637b97d04f2b9e0b7cd275dae9.png

下面我們試圖從源碼(Api 28)角度來分析為什么會出現上面這種打破了安卓程序員固有思維的現象,我們先討論出異常這種情況。從TextView設置文本的方法setText的方法調用棧可知,這個方法會調用View的requestLayout方法,而這個方法最終又會調用ViewRootImpl的checkThread方法,正是在這個方法里拋出了上述異常。

b01d1283563a6cd64f70aa60618e23f5.png

那么我們將TextView的寬度改成足夠大的時候,方法的調用棧又會發生什么變化呢?我們再回到TextView的checkForRelayout方法中,在這個方法的8862行是判斷TextView是否需要根據文本的內容變化來改變控件的大小。如果控件足夠大的話,requestLayout方法將不會調用,所以也不至于去校驗布局操作是在哪個線程處理了。

8b320696a99eafbafd985a322db3a63e.png

綜上,子線程是可以處理UI操作的,只要沒涉及到控件布局變化就行,其實也不僅限于TextView,大家有時間完全可以嘗試其他控件如ImageView。

不過雖然在某些情況下可以在子線做UI操作,但是還是不建議那樣做,因為在開發過程中很難去判斷也沒必要去判斷文本內容會不會超出控件,作為開發者還是要遵守安卓開發規范盡量保證在主線程里操作UI。不過如果有一天面試的時候有人問你主線程是否可以做UI操作的話,你應該能舉出上面這種情況,這樣面試官一定會對你刮目相看。

舉報/反饋

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533758.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533758.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533758.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++注釋快捷鍵_Jupyter Notebook amp; Lab快捷鍵大全

Jupyter有兩種模式,命令模式和編輯模式,分別有不同的快捷鍵。編輯模式(按鍵 Enter 切換):可以往單元中鍵入代碼或文本,此時單元格被藍色的框線包圍,且命令模式下的快捷鍵不生效; 命令模式 (按鍵 Esc 開啟)&…

多核cpu應用場景_CPU占用100%!PC卡頓原來可以這么解決:多場景多任務也流暢

現代生活里,不論是工作還是生活,多開軟件和處理事務可以說都是家常便飯的事情。一邊玩著醉心已久的游戲,一邊解壓著新的電影和游戲;為了查詢資料,一不小心打開了數十個網頁;復雜繁重的工作鑄就了動輒上百兆…

swot分析法案例_項目型銷售案例剖析的五大步驟

我們的案例分析方式是根據哈佛大學與中歐國際工商學院的案例分析方法來總結出我們的模式的。這種分析方法包括兩種互相關聯和依賴的方面。第一方面,就是要對所指定的將供集體討論的案例,做出深刻而有意義的分析,包括找出案例所描述的情景中存…

autojs 云控_autojs websocket 核心示例代碼,云控技術

//初始化方法function recordInit(scriptName){//let ipInfoJson getIP()// let ip ipInfoJson.cip// let location ipInfoJson.cnamelet deviceIMEI ,deviceBrand,deviceModel,AndroidVer,deviceWH,deviceBoard,deviceMac,AndroidIdtry {deviceBrand device.brand;//制造…

定時器和promise_從Promise鏈理解EventLoop

面試題new Promise(resolve > { setTimeout(()>{ console.log(666); new Promise(resolve > { resolve(); }) .then(() > {console.log(777);}) }) resolve(); }) .then(() > { new Promise(resolve > { resolve(); …

ugui源碼_UGUI整體解決方案基礎篇(Unity 2019)

課程介紹:本課程是UGUI系列課程的第一篇:基礎篇主要是講解UGUI的基礎組件及接口的使用方法,目前UGUI是unity最常用的UI系統,這部分基礎只是是每個同學都應該掌握的,這里我就是簡單的講解了用法,大家對UGUI熟…

android 實例源碼解釋,Android Handler 原理分析及實例代碼

Android Handler 原理分析Handler一個讓無數android開發者頭疼的東西,希望我今天這邊文章能為您徹底根治這個問題今天就為大家詳細剖析下Handler的原理Handler使用的原因1.多線程更新Ui會導致UI界面錯亂2.如果加鎖會導致性能下降3.只在主線程去更新UI,輪詢處理Handl…

amd cpu排行_最新intel和amd處理器性能排行cpu天梯圖2019

現在市面上cpu廠家有很多,比如常見的intel系列的、amd系列CPU,cpu對電腦起著至關重要的作用,所以我們需要知道cpu性能的好壞,為此小編這就給大家帶來最新intel和amd處理器性能排行對比天梯圖,大家可以了解一下吧。inte…

python中的對象列表_Python內建的對象列表

Python內建的對象列表剛寫Python肯定會遇到這樣的情況,想寫些什么,但又不知從何寫起...在我看來問題在于我們不知道有什么東東可以拿來玩,這里列出Python的內建對象,稍微歸類了一下,多看幾遍代碼自然筆上生花&#xff…

電腦會顯示android,怎么在電腦上顯示、操作安卓手機

想要在電腦上顯示、操作安卓手機,該怎么辦,那么怎么在電腦上顯示、操作安卓手機的呢?下面是學習啦小編收集整理的怎么在電腦上顯示、操作安卓手機,希望對大家有幫助~~在電腦上顯示、操作安卓手機的方法工具/原料windows操作系統安卓手機電腦…

git version是什么軟件_Deepin 15.11 安裝 ZoneMinder 視頻監控軟件

Zoneminder是一款開源的視頻監控軟件,可以很方便的連接ip攝像頭。因計劃將家中的監控攝像頭引入NAS,在一臺deepin系統的筆記本是先進行了測試。UBUNTU和debian系統都是很容易安裝這個軟件的。未來在NAS上用docker啟動一個專門的zoneminder,do…

看不出svp補幀_專業補幀軟件SVP4 實現PotPlayer視頻補幀教程

雖然能實現幀率翻倍,不過現在視頻絕大多數都是24幀或25幀,翻倍也才48幀,沒辦法實現補幀后達到60幀的效果。SVP4是一款專業版視頻補幀軟件,提供GPU加速,并允許使用中檔CPU和幾乎任何GPU硬件為60Hz的FullHD 1080p視頻重新…

android 通知歷史,Android P新特性:追蹤應用通知歷史

原標題:Android P新特性:追蹤應用通知歷史IT之家3月9日消息 不久前,谷歌已經正式推出了首個Android P開發者預覽版,包含了許多新特性。對此,IT之家也進行了一系列報道。該系統的新特性也正在不斷被發現。例如最新消息顯…

文件另存為時名稱會改變_易經:人處在困境時,不要焦慮,改變固定習慣,就會迎來轉機...

我讀《易經》,悟到一些規律:人的一生,起起落落,時而順利,時而受困,都是正常現象,沒有必要把困難和壓力看得太重。人處在困境時,不要焦慮,只要改變你的固定習慣&#xff0…

ubuntu系統寫路由指令_在Ubuntu中如何查看網絡路由表詳解,

在Ubuntu中如何查看網絡路由表詳解,什么是Linux中的路由和路由表?路由的過程意味著IP包在網絡上從一點傳輸到另一點。當你向某人發送電子郵件時,你實際上是在將一系列IP數據包或數據報從你的系統傳輸到另一個人的計算機上。從計算機發送的數據…

jspdf html轉換pdf,使用jspdf將HTML轉換為pdf時出錯

對于一個角度項目,我試圖將包含HTML代碼的字符串變量轉換為pdf文件。我安置了所有的家屬,比如:jspdf格式光柵化HTML我的代碼如下:b64DecodeUnicode(str) {return decodeURIComponent(atob(str).split().map(function(c) {return % (00 c.charCodeAt(0).toString(16)).slice(-…

澄海哪里學機器人編程_終于發現小孩有必要學機器人編程嗎

讓孩子學習編程的目的,就像其他教育方式一樣,只是希望能幫助孩子找到他的興趣點,打開孩子的獲取知識和能力的大門。一起來看看一篇小孩有必要學機器人編程嗎。小孩有必要學機器人編程嗎編程和英語類似,屬于基本技能,未…

鴻蒙系統替代iOS,華為橫空出世!鴻蒙系統,能否替代安卓IOS?

原標題:華為橫空出世!鴻蒙系統,能否替代安卓IOS?從長遠來看,華為主推鴻蒙系統是必然的選擇。畢竟安卓系統為谷歌的,而由于美國限制,讓華為格外被動。命運掌握在自己手里,才有足夠的話…

ubuntu安裝python3.8_將 Ubuntu 16 和 18 上的 python 升級到最新 python3.8 的方法教程

1. 概述 本文記錄在 Ubuntu 16.04 上將 python 升級為 3.8 版本,并配置為系統默認 python3 的過程。 在 Ubuntu 16.04 中,python3 的默認版本為 3.5: $ python3 -V Python 3.5.2 本文以在 Ubuntu 16.04 中安裝為例,方法同樣適用于…

java怎么表示正無窮大_java中怎樣表示一個無窮大? 無窮小?

Java中提供了三個特殊的浮點數值:正無窮大、負無窮大、非數,用于表示溢出和出錯。正無窮大:用一個正數除以0將得到一個正無窮大,通過Double或Float的POSITIVE_INFINITY表示。負無窮大:用一個負數除以0將得到一個負無窮…