背景
在我的flutter项目中,从A组件导航到B组件后,B组件在软键盘弹起与收起的时候,A组件会不断调用didUpdateWidget和build。
初步排查
起初以为是路由的问题,经过排查后发现,Navigator确实存在历史问题,会导致oldWidget的rebuild。
在1.17版本之后,这个问题已经被修复了,开发者不再需要额外的工作即可避免。
发现端倪
继续排查了很多地方,本以为可能出现问题的菜单组件、MediaQuery的不合适的调用等等,都没有发现问题。
开始从下往上思考:如果组件本身没有调用setState,没有继承InheritedWidget,那发生预期外的生命周期函数调用,一定是它的context在其他地方发生预期外的使用了。
找到凶手
搜索A组件里所有用到context的地方,果不其然,凶手找到了:
precacheImage(NetworkImage(Constants.bgUrl), context);
复制代码
进入precacheImage的源码后,很容易找到context被注册到了MediaQuery.maybeOf,剩下的就很好理解了:
MediaQuery继承自InheritedWidget;
软键盘调用时,MediaQueryData会变化,所有通过MediaQuery.maybeOf和MediaQuery.of注册的组件都会更新。
总结
- 深入理解
Flutter的生命周期和更新逻辑,在遇到相关的问题时总是能从源码和原理上找到解决办法。 - 保护好组件的
context。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)