開發(fā)中避免延時(shí)操作技巧詳解
前言
開發(fā)中我們或多或少會(huì)涉及到一些場(chǎng)景需要使用延時(shí)操作,而延時(shí)操作其實(shí)并不是一個(gè)很好的選擇,并不是一個(gè)很好的方案,因?yàn)樗豢煽?,也可能產(chǎn)生時(shí)序的邏輯問題。這次就來(lái)盤點(diǎn)一些使用延時(shí)操作的場(chǎng)景和如何去避免,本次內(nèi)容比較基礎(chǔ)。
使用延時(shí)的場(chǎng)景
在剛接觸開發(fā)的時(shí)候,我們無(wú)腦解決問題的方案基本只有兩種,異常捕獲和延時(shí)。異常捕獲容易理解,當(dāng)碰到崩潰又分析不出原因時(shí),往往加個(gè)try-catch就能繞過,但往往這樣做只會(huì)導(dǎo)致出現(xiàn)更難排查的BUG,當(dāng)慢慢有經(jīng)驗(yàn)的時(shí)候,也不會(huì)再這么做了,畢竟crash提示出來(lái)的BUG也都比較好解決。
其實(shí)延時(shí)操作也是這樣,找不到問題出在哪里,然后胡亂嘗試,發(fā)現(xiàn)在某個(gè)地方加個(gè)延時(shí)幾秒就能讓流程正常。其實(shí)這個(gè)和亂加異常捕獲一樣,往往會(huì)引發(fā)更難排查的問題,所以有問題就平下心解決問題,不要試圖使用這種方式。這也是延時(shí)操作最不應(yīng)該出現(xiàn)的方式。
獲取view的寬高
剛開始接觸的時(shí)候,往往不會(huì)正確的獲取view的寬高,直接就view.getHeight()然后發(fā)現(xiàn)獲取到的高度是0,然后不知道為什么,開始瞎嘗試,最終嘗試出加個(gè)延時(shí)1秒就能獲取到高度。
但是這并不能解決辦法,這時(shí)正確的做法應(yīng)該是去了解view的繪制流程,去探究為什么一開始獲取不到值,去看源碼(當(dāng)然一開始自己瞎看源碼有點(diǎn)難),去看看這個(gè)東西是怎樣的一個(gè)機(jī)制,然后結(jié)合這些甚至結(jié)合別人的分析,再去看源碼,就很容易能看得。
就能知道為什么應(yīng)該用view.post
定時(shí)查詢服務(wù)器結(jié)果
假如你有一個(gè)應(yīng)用,你怎么知道你何時(shí)被人搶登,你何時(shí)能收到別人的消息,等等。往往很多人的做法是寫一個(gè)定時(shí)器,每隔多長(zhǎng)時(shí)間去向服務(wù)器發(fā)送http請(qǐng)求查詢一下狀態(tài),那么這樣的做法沒問題嗎?
如果你把細(xì)節(jié)都處理好,這樣的做法當(dāng)然沒問題,但有沒有了解過有一個(gè)協(xié)議叫websocket,你總有見過有些鏈接不是http開頭,而是ws開頭的吧。有沒有了解過一個(gè)協(xié)議叫MQTT,沒了解過也沒關(guān)系,可以看看我這篇基礎(chǔ)的文章:http://www.dbjr.com.cn/article/276761.htm,甚至上升到智能硬件層面,有沒有了解過什么是IOT。
當(dāng)然不是說輪詢請(qǐng)求有問題,只是需要處理一些細(xì)節(jié),中斷什么的,甚至如果有更好的方法能實(shí)現(xiàn)你想要的效果,那為何不用更好的呢?
但是如果你是要定時(shí)執(zhí)行某些本地的任務(wù),那用定時(shí)器倒是沒有什么問題,關(guān)鍵要處理好一些細(xì)節(jié),生命周期、中斷操作、暫停操作等等。
廣播順序
復(fù)雜的多應(yīng)用情況下,往往或多或少會(huì)使用到廣播,那其實(shí)廣播的注冊(cè)和廣播的發(fā)送,就是有個(gè)順序問題。有可能你的某些邏輯導(dǎo)致廣播先發(fā)送,另外一邊再注冊(cè),那就會(huì)出現(xiàn)接收不到廣播的情況。有些人為了簡(jiǎn)單處理這個(gè)問題,往往會(huì)加個(gè)延時(shí),讓廣播延時(shí)發(fā)送。
那這其實(shí)是個(gè)很危險(xiǎn)的操作,正確的做法是,應(yīng)該去對(duì)廣播這個(gè)東西有一定的了解。你就會(huì)知道有種廣播類型叫粘性廣播,哪怕你熟悉了這個(gè)領(lǐng)域的知識(shí),還是不了解它或者說它對(duì)你來(lái)說在這個(gè)場(chǎng)景不適用,那你也會(huì)有更好的辦法去解決這個(gè)問題,而不是通過延時(shí)這種不安全的操作。
延時(shí)初始化
我們都知道在Application或者在onCreate中做過多的初始化操作是不好的,大家都知道優(yōu)化,優(yōu)化啟動(dòng)速度,所以不會(huì)在這些地方做初始化。那有些人就會(huì)想出一些騷辦法,我在這些地方加個(gè)延時(shí),延時(shí)個(gè)一兩秒再做初始化,這樣又能優(yōu)化啟動(dòng)速度,又能在對(duì)應(yīng)的功能使用前進(jìn)行初始化,豈不美哉?你覺得呢
你的延時(shí)的原理是什么,handler機(jī)制,那有沒有了解有個(gè)東西叫IdleHandler。
其實(shí)單獨(dú)用IdleHandler也不是一個(gè)安全的操作,那為什么不放在第一次使用的時(shí)候再給功能做初始化呢?有的人可能會(huì)說,如果初始化是耗時(shí)操作,那在第一次使用的時(shí)候再進(jìn)行初始化,就會(huì)影響使用的體驗(yàn)。對(duì)于這個(gè)問題,我一般情況是一起使用,又在IdleHandler進(jìn)行初始化,也在第一次使用的時(shí)候判斷沒有初始化的話再進(jìn)行初始化。特殊的情況可以在某些地方進(jìn)行,這個(gè)要看具體的需求。
使用延時(shí)的場(chǎng)景
那既然延時(shí)是一個(gè)這么危險(xiǎn)的操作,并且一般都有更好的方式去替代,那我們是不是就打死都不使用延時(shí)操作。并不是,有時(shí)候不用還真不行,那是什么時(shí)候需要使用?當(dāng)然是沒辦法通過其它方法去處理這個(gè)問題的時(shí)候。用,但是要小心用。
比如我調(diào)用別人的一個(gè)庫(kù),那個(gè)庫(kù)里做了操作,然后給我回調(diào),這是一個(gè)基本的流程嘛。但是,這個(gè)庫(kù)不是你的,可能他寫了BUG或者什么原因,導(dǎo)致你調(diào)用他的方法,但他不給你回調(diào)。那這種情況下如果你不做什么操作,你就會(huì)一直卡在這。
所以針對(duì)這種情況,一般會(huì)做個(gè)超時(shí)機(jī)制去讓這個(gè)流程更安全一些,比如說你20秒不給我回調(diào),我就返回失敗。當(dāng)然我覺得首先應(yīng)該和庫(kù)的作者去溝通這個(gè)問題,實(shí)在沒辦法了,才用這種下下策。
但是如果這么做了,那要注意狀態(tài),比如說你已經(jīng)超時(shí)了,要是他這時(shí)候再給你回調(diào)怎么辦?所以用這種方法,還需要寫很多東西去保證它的安全。
還有一種情況是Loading,這個(gè)可能我從以前開始就這樣操作比較多,Loading的時(shí)候我不會(huì)馬上顯示菊花轉(zhuǎn),會(huì)延時(shí)0.5秒再顯示,這樣能有比較好的體驗(yàn)。
當(dāng)然還有你想先寫個(gè)延時(shí),然后過幾個(gè)版本你和你老板說,我要做個(gè)優(yōu)化,然后你把延時(shí)給去掉,看到?jīng)]有,速度明顯快了,如果你想這樣玩,那就當(dāng)我沒說。
還有,你這種延時(shí)也是有講究的,比如我做重繪更新頁(yè)面后頁(yè)面顯示后才做某些操作,那我怎么做,系統(tǒng)有方法實(shí)現(xiàn),如果你說我就要做延時(shí)(我這里為了舉個(gè)例子),那你就要知道屏幕刷新是16ms,但如果沒畫完,會(huì)放到下次刷新,為了安全,你可以設(shè)置高一些,你可以設(shè)80ms的延時(shí),但沒必要設(shè)到一兩秒。
小心使用延時(shí)
為什么說要盡量避免使用延時(shí)操作,因?yàn)檫@個(gè)操作確實(shí)坑多,在Android中大部分的延時(shí)操作都會(huì)用postDelayed去實(shí)現(xiàn)。
首先你要考慮一個(gè)問題,中斷問題,需要有個(gè)中斷機(jī)制,比如你在Activity做了延時(shí)操作,但是Activity銷毀了,這時(shí)候你延時(shí)時(shí)間到了難道還要繼續(xù)執(zhí)行操作?所以會(huì)在Activity的onDestroy里面去移除Handler的消息。
假設(shè)你加了中斷操作,但是只這樣做安全嗎?有沒有考慮過你中斷的時(shí)候其實(shí)消息已經(jīng)開始處理了。所以這時(shí)候還需要用一個(gè)狀態(tài)去做判斷,根據(jù)這個(gè)狀態(tài)判斷Activity是否被銷毀,被消耗了就不執(zhí)行后面的操作。
這里也只是列舉其中一個(gè)場(chǎng)景,其實(shí)在使用延時(shí)的時(shí)候往往會(huì)很危險(xiǎn),所以使用需謹(jǐn)慎,能不用就不用,如果一定要用,也需要考慮周全。
以上就是開發(fā)中避免延時(shí)操作技巧詳解的詳細(xì)內(nèi)容,更多關(guān)于避免延時(shí)操作技巧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Sublime將數(shù)據(jù)json格式化的操作方法
這篇文章主要介紹了Sublime將數(shù)據(jù)json格式化的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Vs?Code配置前端環(huán)境及運(yùn)行詳細(xì)指南
相信越來(lái)越多的前端開發(fā)者已經(jīng)遷移到VSCode陣營(yíng)了,下面這篇文章主要給大家介紹了關(guān)于Vs?Code配置前端環(huán)境及運(yùn)行的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10推薦幾個(gè)好用的WordPress媒體庫(kù)分類/文件夾管理插件
這篇文章主要介紹了推薦幾個(gè)好用的WordPress媒體庫(kù)分類/文件夾管理插件2021-09-09VScode設(shè)置語(yǔ)言為中文以及解決中文注釋亂碼問題
VSCode默認(rèn)是英文語(yǔ)言環(huán)境,習(xí)慣了用中文,下面這篇文章主要給大家介紹了關(guān)于VScode設(shè)置語(yǔ)言為中文以及解決中文注釋亂碼問題的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12vs2022使用git同步報(bào)錯(cuò)以及解決每次推送要輸入密碼問題
本文主要介紹了vs2022使用git同步報(bào)錯(cuò)以及解決每次推送要輸入密碼問題,文中通過圖文示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10