业务分析
很多App都需要处理如下两个场景:
- 在启动时根据是否登录过跳转不同页面,期间App要处于启动图位置
- 在启动时根据之前所选择的环境使用不同域名,期间App要处于启动图位置
要实现这种场景,要解决一个根本性问题:
如何让启动图的消失变的可控
我最开始的思路是,既然真的不好控制,那就控制假的
,思路如下:
- 增加一个Launch路由,该路由全屏加载启动图
- 在Launch路由内做后续路由分发
- 将该Launch路由设置为初始路由
这个思路咋一看好像没啥毛病,但提测后QA同学发现了两个细节问题:
- Launch路由启动图和Native启动图虽然是同一张图片,但两者在切换时似乎有一定的错位。该问题的解决方式简单,可以通过修改填充方式去处理,还有其他问题可以留下评论,一块探讨。
- 在Native启动图切换到Launch启动图时,中间的过渡会闪烁,在低端机型上尤为明显。经过测试发现,并非切换造成的闪烁,而是Launch启动图的加载时间在性能不同的机型上会有差异。
第二个问题,我也曾经想过一些方案,比如:
- 压缩图片、将图片变为base64格式(用base64的方式我没试,有兴趣的可以试试)
- 改动Native代码
前者虽然让效果有一点的优化,但效果还差那么一点意思。后者的话不想试,首先嫌麻烦,其次是并非所有的Flutter开发都懂原生,无法形成通用方案。
因此最后又回到了最初的问题:
如何让Native启动图的消失时间变得可控
解决方案
在各种google以后,有个博客(地址找不到了)提到:
Flutter项目的Native启动图和纯Native项目的启动图在消失时间上是有差异的,在Flutter中Native启动图消失是在调用
runApp
后。
好家伙,欣喜若狂呀。试了一下,还真是。
业务实践
在最开始提到的两种场景中,其实逻辑是一致的,都是老三步:
- 从本地缓存(SharePreferences)中获取值
- 将值放到内存中
- 根据业务逻辑,设置初始路由
在实践中发现一个大坑:
若要在
runApp
之前使用SharePreferences
,必须优先调用WidgetsFlutterBinding.ensureInitialized();
有兴趣的话可以研究一下runApp
内部都做了啥,会有些惊喜的发现哦,至于这个坑,原理还没有搞懂,有兴趣可以留言讨论一下。