开启生长之旅!这是我参加「日新计划 2 月更文挑战」的第 17 天,点击检查活动详情

前语

开发中咱们或多或少会涉及到一些场景需求运用延时操作,而延时操作其实并不是一个很好的选择,并不是一个很好的方案,因为它不可控,也或许发生时序的逻辑问题。这次就来盘点一些运用延时操作的场景和如何去避免,本次内容比较基础。

运用延时的场景

在刚触摸开发的时分,咱们无脑解决问题的方案根本只有两种,反常捕获和延时。反常捕获简单理解,当碰到溃散又剖析不出原因时,往往加个try-catch就能绕过,但往往这样做只会导致呈现更难排查的BUG,当慢慢有经验的时分,也不会再这么做了,究竟crash提示出来的BUG也都比较好解决。

其实延时操作也是这样,找不到问题出在哪里,然后胡乱尝试,发现在某个当地加个延时几秒就能让流程正常。其实这个和乱加反常捕获一样,往往会引发更难排查的问题,所以有问题就平下心解决问题,不要企图运用这种方式。这也是延时操作最不应该呈现的方式。

获取view的宽高

刚开始触摸的时分,往往不会正确的获取view的宽高,直接就view.getHeight()然后发现获取到的高度是0,然后不知道为什么,开始瞎尝试,最终尝试出加个延时1秒就能获取到高度。

可是这并不能解决办法,这时正确的做法应该是去了解view的制作流程,去探究为什么一开始获取不到值,去看源码(当然一开始自己瞎看源码有点难),去看看这个东西是怎样的一个机制,然后结合这些乃至结合他人的剖析,再去看源码,就很简单能看得。

就能知道为什么应该用view.post

守时查询服务器结果

假如你有一个运用,你怎样知道你何时被人抢登,你何时能收到他人的音讯,等等。往往很多人的做法是写一个守时器,每隔多长时刻去向服务器发送http恳求查询一下状况,那么这样的做法没问题吗?

假如你把细节都处理好,这样的做法当然没问题,但有没有了解过有一个协议叫websocket,你总有见过有些链接不是http最初,而是ws最初的吧。有没有了解过一个协议叫MQTT,没了解过也没关系,能够看看我这篇基础的文章:/post/713918… ,乃至上升到智能硬件层面,有没有了解过什么是IOT。

当然不是说轮询恳求有问题,仅仅需求处理一些细节,中止什么的,乃至假如有更好的办法能完成你想要的作用,那为何不必更好的呢?

可是假如你是要守时履行某些本地的任务,那用守时器倒是没有什么问题,关键要处理好一些细节,生命周期、中止操作、暂停操作等等。

播送次序

复杂的多运用状况下,往往或多或少会运用到播送,那其实播送的注册和播送的发送,便是有个次序问题。有或许你的某些逻辑导致播送先发送,别的一边再注册,那就会呈现接收不到播送的状况。有些人为了简单处理这个问题,往往会加个延时,让播送延时发送。

那这其实是个很风险的操作,正确的做法是,应该去对播送这个东西有必定的了解。你就会知道有种播送类型叫粘性播送,哪怕你熟悉了这个范畴的常识,还是不了解它或许说它对你来说在这个场景不适用,那你也会有更好的办法去解决这个问题,而不是经过延时这种不安全的操作。

延时初始化

咱们都知道在Application或许在onCreate中做过多的初始化操作是不好的,大家都知道优化,优化发动速度,所以不会在这些当地做初始化。那有些人就会想出一些骚办法,我在这些当地加个延时,延时个一两秒再做初始化,这样又能优化发动速度,又能在对应的功能运用前进行初始化,岂不美哉?你觉得呢

你的延时的原理是什么,handler机制,那有没有了解有个东西叫IdleHandler。

其实单独用IdleHandler也不是一个安全的操作,那为什么不放在第一次运用的时分再给功能做初始化呢?有的人或许会说,假如初始化是耗时操作,那在第一次运用的时分再进行初始化,就会影响运用的体验。对于这个问题,我一般状况是一同运用,又在IdleHandler进行初始化,也在第一次运用的时分判别没有初始化的话再进行初始化。特别的状况能够在某些当地进行,这个要看详细的需求。

运用延时的场景

那既然延时是一个这么风险的操作,并且一般都有更好的方式去替代,那咱们是不是就打死都不运用延时操作。并不是,有时分不必还真不行,那是什么时分需求运用?当然是没办法经过其它办法去处理这个问题的时分。用,可是要当心用。

比如我调用他人的一个库,那个库里做了操作,然后给我回调,这是一个根本的流程嘛。可是,这个库不是你的,或许他写了BUG或许什么原因,导致你调用他的办法,但他不给你回调。那这种状况下假如你不做什么操作,你就会一向卡在这。

所以针对这种状况,一般会做个超时机制去让这个流程更安全一些,比如说你20秒不给我回调,我就回来失败。当然我觉得首先应该和库的作者去沟通这个问题,实在没办法了,才用这种下下策。

可是假如这么做了,那要注意状况,比如说你已经超时了,要是他这时分再给你回调怎样办?所以用这种办法,还需求写很多东西去保证它的安全。

还有一种状况是Loading,这个或许我从曾经开始就这样操作比较多,Loading的时分我不会立刻显现菊花转,会延时0.5秒再显现,这样能有比较好的体验。

当然还有你想先写个延时,然后过几个版本你和你老板说,我要做个优化,然后你把延时给去掉,看到没有,速度显着快了,假如你想这样玩,那就当我没说。

还有,你这种延时也是有讲究的,比如我做重绘更新页面后页面显现后才做某些操作,那我怎样做,系统有办法完成,假如你说我就要做延时(我这儿为了举个例子),那你就要知道屏幕改写是16ms,但假如没画完,会放到下次改写,为了安全,你能够设置高一些,你能够设80ms的延时,但没必要设到一两秒。

当心运用延时

为什么说要尽量避免运用延时操作,因为这个操作的确坑多,在Android中大部分的延时操作都会用postDelayed去完成。

首先你要考虑一个问题,中止问题,需求有个中止机制,比如你在Activity做了延时操作,可是Activity销毁了,这时分你延时时刻到了难道还要持续履行操作?所以会在Activity的onDestroy里边去移除Handler的音讯。

假设你加了中止操作,可是只这样做安全吗?有没有考虑过你中止的时分其实音讯已经开始处理了。所以这时分还需求用一个状况去做判别,根据这个状况判别Activity是否被销毁,被消耗了就不履行后面的操作。

这儿也仅仅列举其中一个场景,其实在运用延时的时分往往会很风险,所以运用需谨慎,能不必就不必,假如必定要用,也需求考虑周全。