快应用开发技巧之判断退到后台篇
来源:快应用官方论坛
作者:zephyrtune
最近碰到一些开发者在咨询:快应用“如何判断退到后台”的问题。正好之前在写功能的时候,也遇到过这个问题,我觉得可以和大家分享下我的经验。
解决这个问题的时候,确实费了我不少脑细胞。作为一个已入坑的老人,想对新入坑的开发者说一句:不入不知坑深,一入一坑到底!
玩笑归玩笑,问题归问题,需求还是要解决的。
目录:
-
【生命周期】探索
-
【退到后台】实现原理
-
【回到前台】及【特殊场景】处理
-
【代码实现】
【生命周期】探索
快应用的生命周期,我就不再赘述了,大家可以参考官方文档:
ttps://doc.quickapp.cn/tutorial/framework/lifecycle.html。
可以看到快应用提供了2个APP级别的事件,7个页面级别的事件、2个页面状态变量。
在这所有的事件和变量里面,没有为【退到后台】和【回到前台】提供单独的回调事件。所以解决这个问题,变得有些棘手,尤其当时还是新手的我,略懵!
但需求还是要做,不过需求延期了。(这里要感谢下领导,还是比较宽容的!)
期间我把所有的事件回调都调试了一遍,依然没什么收获。一番折腾以后,我决定还是把所有的目光都聚焦到onHide()和onShow()这两个事件上。
单独看onHide()这个事件,它在页面被切换隐藏时调用,不管页面是【跳转】还是【退到后台】,都会触发这个事件。所以只要能把【跳转】和【退到后台】区分出来,问题就引刃而解了。
想到这一点的我,感觉眼前一切光明!但具体如何区分呢?瞬间又让我陷入了深深的沉思之中。
抬头望天,天花板让我别看,它就是天。再看看周围的小伙伴,他们的眼神中似乎散发出一种诡异的光芒,仿佛在提醒我一个事实:你是我这辈子见过的最销魂的懵逼!
但四分之一炷香之后,我会让他们知道,我解决了这个问题。虽然本人生平解决过无数问题,但是这一次,我认为是最开心的。做开发,写代码呢,最重要的就是开心……
退到后台】实现原理
在翻了【TVB经典台词100句】和【快应用开发文档】之后,收到线报,说:
router.getState().name,获取当前页面名称。通过页面名称来判断【页面跳转】和【退到后台】。
我问线人:你是不是想说,【页面跳转】的名称不一样,而【退到后台】的页面名称是一样的?。
线人斩钉截铁地说:是!
(我若有所思,这样判断真的可行么?有没有内鬼?会不会出意外?)
突然,我厉声喝道:臭小子,你耍我么?
线人一惊:阿Sir,相信我,这是刚刚得到的最新消息……
我:如果对方同名同姓怎么办?就比如一个商品页跳另一个商品页,他们都一个名字,只是id参数不同而已。你说这是跳转?还是退到后台?
线人:……
(通过页面名称判断的方式应该是不可行了,但我灵机一动,久违的笑容不禁出现在脸上)
我:你这消息虽不准确,但也有一定价值,我们可以把判断方式改一改,改成比较页面对象,这样就行了!
线人:阿Sir,好厉害!阿Sir,好威武!
我:嘿嘿嘿!
就这样,我写了【退到后台】的第一个版本,但后来发生的一件事情,让我觉得这个版本还是有些不足之处……
【回到前台】及【特殊场景】处理
正当我根据【退到后台】的经验,写【回到前台】的逻辑时,正当我以为无往不利,大功即将告成之时,突然手机响起:有内鬼终止交易!
我:……
(此时的我,心里的崩溃和绝望,如同瞬间跌落谷底,我想去天台透透风!)
(站在天台屋顶边,世界变得如此的渺小,以往我也无数次站在这个位置,以同样的角度看着所有的一切。但这一次我看不清楚!一切都变得那么暗淡朦胧!)
(兜里的iPhone突然振了一下。我摸出手机,定睛一看!我擦!原来现在是凌晨4点…………………………)
(手机上的内容写的是:你不是开发快应用的吗?为什么用iPhone?!)
我:……
(就在此时,背后突然有人大喊:别跳楼,这个月的指标用完了,不准跳!)
我:……
(我回头看了一眼,原来是他!)
我:保安做的还习惯吧?
他:习惯!到哪不是为人民(币)服务?!
我:上个月往你二姑家表弟帐上打的钱收到了吧?
他:收到了。就是税扣得有点多,肉疼!
我:你那身懒肉,是该减减肥了!好好干吧,总有一天你会搬进汤臣一品的!因为马云说,未来的房子会变成白菜价的!
他:……
我:刚刚的短信是怎么回事?
他:你说内鬼那事?
我:嗯!
他:我打听到,快应用router接口是可以直接跳网页的,可能会影响上面的逻辑判断。
我:router.push()和router.replace()?
他:是的,就是这两个内鬼。
我:嗯,如果是网页地址的话,他们会调用System.Web打开网页,虽然页面被切走了,但新页面中,并没有触发我们自定义的onShow()和onHide()事件, 所以会导致上面的判断逻辑失效。
他:对!
我:咱们可以单独写个ViewModel来承接所有的WebView页面,你说问题是不是就解决了?
他:好主意!这么好的主意,咱要不要先拆包辣条庆祝一下?
(我投过去鄙夷的眼神,一包哪够分?还不够你个胖子塞牙缝的!)
我:辣条还是你吃吧!我觉得还有一种思路,也可以解决这个问题。
他:还有一种?
我:嗯!只要对System.Web做一个特殊判断就可以了!
他:咋弄?
我:看代码吧!talk is cheap, show you my code.
【代码实现】
先定义一个公共lib,page.js:
const $ = Object.getPrototypeOf(global) || global
import router from '@system.router'
export default $.page = {
lastPage: '',
onShow(self) {
if (this.lastPage === self) {
console.log('回到前台')
} else {
console.log('页面显示')
this.lastPage = self
}
},
onHide(self) {
console.log('页面隐藏')
if (router.getState().name === 'System.Web') {
this.lastPage = null
} else {
let t = setTimeout(() => {
if (this.lastPage === self) {
console.log('退到后台')
}
clearTimeout(t)
}, 500)
}
}
}
再在各个ViewModel中的onShow()和onHide()里调用:
export default {
...
...
onShow() {
$.page.onShow(this)
},
onHide() {
$.page.onHide(this)
},
...
...
}
以上代码,结合前文的描述,应该一看就懂,整体代码量也不多,但实实在在解决了【退到后台】和【回到前台】的判断问题。其中,有一段setTimeout(),大家可以自行思考下,为什么要加这段。总之,得出此段代码的思考过程是非常有意思的,废了不少脑细胞,写出来,希望能给新手小白一些启发。
扫码关注,敬请期待快应用更多精彩内容!
快来关注我们吧