首頁 > 軟體

開發中避免延時操作技巧詳解

2023-03-02 18:01:07

前言

開發中我們或多或少會涉及到一些場景需要使用延時操作,而延時操作其實並不是一個很好的選擇,並不是一個很好的方案,因為它不可控,也可能產生時序的邏輯問題。這次就來盤點一些使用延時操作的場景和如何去避免,本次內容比較基礎。

使用延時的場景

在剛接觸開發的時候,我們無腦解決問題的方案基本只有兩種,異常捕獲和延時。異常捕獲容易理解,當碰到崩潰又分析不出原因時,往往加個try-catch就能繞過,但往往這樣做只會導致出現更難排查的BUG,當慢慢有經驗的時候,也不會再這麼做了,畢竟crash提示出來的BUG也都比較好解決。

其實延時操作也是這樣,找不到問題出在哪裡,然後胡亂嘗試,發現在某個地方加個延時幾秒就能讓流程正常。其實這個和亂加異常捕獲一樣,往往會引發更難排查的問題,所以有問題就平下心解決問題,不要試圖使用這種方式。這也是延時操作最不應該出現的方式。

獲取view的寬高

剛開始接觸的時候,往往不會正確的獲取view的寬高,直接就view.getHeight()然後發現獲取到的高度是0,然後不知道為什麼,開始瞎嘗試,最終嘗試出加個延時1秒就能獲取到高度。

但是這並不能解決辦法,這時正確的做法應該是去了解view的繪製流程,去探究為什麼一開始獲取不到值,去看原始碼(當然一開始自己瞎看原始碼有點難),去看看這個東西是怎樣的一個機制,然後結合這些甚至結合別人的分析,再去看原始碼,就很容易能看得。

就能知道為什麼應該用view.post

定時查詢伺服器結果

假如你有一個應用,你怎麼知道你何時被人搶登,你何時能收到別人的訊息,等等。往往很多人的做法是寫一個定時器,每隔多長時間去向伺服器傳送http請求查詢一下狀態,那麼這樣的做法沒問題嗎?

如果你把細節都處理好,這樣的做法當然沒問題,但有沒有了解過有一個協定叫websocket,你總有見過有些連結不是http開頭,而是ws開頭的吧。有沒有了解過一個協定叫MQTT,沒了解過也沒關係,可以看看我這篇基礎的文章:https://www.jb51.net/article/276761.htm,甚至上升到智慧硬體層面,有沒有了解過什麼是IOT。

當然不是說輪詢請求有問題,只是需要處理一些細節,中斷什麼的,甚至如果有更好的方法能實現你想要的效果,那為何不用更好的呢?

但是如果你是要定時執行某些原生的任務,那用定時器倒是沒有什麼問題,關鍵要處理好一些細節,生命週期、中斷操作、暫停操作等等。

廣播順序

複雜的多應用情況下,往往或多或少會使用到廣播,那其實廣播的註冊和廣播的傳送,就是有個順序問題。有可能你的某些邏輯導致廣播先傳送,另外一邊再註冊,那就會出現接收不到廣播的情況。有些人為了簡單處理這個問題,往往會加個延時,讓廣播延時傳送。

那這其實是個很危險的操作,正確的做法是,應該去對廣播這個東西有一定的瞭解。你就會知道有種廣播型別叫粘性廣播,哪怕你熟悉了這個領域的知識,還是不瞭解它或者說它對你來說在這個場景不適用,那你也會有更好的辦法去解決這個問題,而不是通過延時這種不安全的操作。

延時初始化

我們都知道在Application或者在onCreate中做過多的初始化操作是不好的,大家都知道優化,優化啟動速度,所以不會在這些地方做初始化。那有些人就會想出一些騷辦法,我在這些地方加個延時,延時個一兩秒再做初始化,這樣又能優化啟動速度,又能在對應的功能使用前進行初始化,豈不美哉?你覺得呢

你的延時的原理是什麼,handler機制,那有沒有了解有個東西叫IdleHandler。

其實單獨用IdleHandler也不是一個安全的操作,那為什麼不放在第一次使用的時候再給功能做初始化呢?有的人可能會說,如果初始化是耗時操作,那在第一次使用的時候再進行初始化,就會影響使用的體驗。對於這個問題,我一般情況是一起使用,又在IdleHandler進行初始化,也在第一次使用的時候判斷沒有初始化的話再進行初始化。特殊的情況可以在某些地方進行,這個要看具體的需求。

使用延時的場景

那既然延時是一個這麼危險的操作,並且一般都有更好的方式去替代,那我們是不是就打死都不使用延時操作。並不是,有時候不用還真不行,那是什麼時候需要使用?當然是沒辦法通過其它方法去處理這個問題的時候。用,但是要小心用。

比如我呼叫別人的一個庫,那個庫裡做了操作,然後給我回撥,這是一個基本的流程嘛。但是,這個庫不是你的,可能他寫了BUG或者什麼原因,導致你呼叫他的方法,但他不給你回撥。那這種情況下如果你不做什麼操作,你就會一直卡在這。

所以針對這種情況,一般會做個超時機制去讓這個流程更安全一些,比如說你20秒不給我回撥,我就返回失敗。當然我覺得首先應該和庫的作者去溝通這個問題,實在沒辦法了,才用這種下下策。

但是如果這麼做了,那要注意狀態,比如說你已經超時了,要是他這時候再給你回撥怎麼辦?所以用這種方法,還需要寫很多東西去保證它的安全。

還有一種情況是Loading,這個可能我從以前開始就這樣操作比較多,Loading的時候我不會馬上顯示菊花轉,會延時0.5秒再顯示,這樣能有比較好的體驗。

當然還有你想先寫個延時,然後過幾個版本你和你老闆說,我要做個優化,然後你把延時給去掉,看到沒有,速度明顯快了,如果你想這樣玩,那就當我沒說。

還有,你這種延時也是有講究的,比如我做重繪更新頁面後頁面顯示後才做某些操作,那我怎麼做,系統有方法實現,如果你說我就要做延時(我這裡為了舉個例子),那你就要知道螢幕重新整理是16ms,但如果沒畫完,會放到下次重新整理,為了安全,你可以設定高一些,你可以設80ms的延時,但沒必要設到一兩秒。

小心使用延時

為什麼說要儘量避免使用延時操作,因為這個操作確實坑多,在Android中大部分的延時操作都會用postDelayed去實現。

首先你要考慮一個問題,中斷問題,需要有個中斷機制,比如你在Activity做了延時操作,但是Activity銷燬了,這時候你延時時間到了難道還要繼續執行操作?所以會在Activity的onDestroy裡面去移除Handler的訊息。

假設你加了中斷操作,但是隻這樣做安全嗎?有沒有考慮過你中斷的時候其實訊息已經開始處理了。所以這時候還需要用一個狀態去做判斷,根據這個狀態判斷Activity是否被銷燬,被消耗了就不執行後面的操作。

這裡也只是列舉其中一個場景,其實在使用延時的時候往往會很危險,所以使用需謹慎,能不用就不用,如果一定要用,也需要考慮周全。

以上就是開發中避免延時操作技巧詳解的詳細內容,更多關於避免延時操作技巧的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com