Flutter Exception降到万分之几的秘密

Posted 闲鱼技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter Exception降到万分之几的秘密相关的知识,希望对你有一定的参考价值。

Flutter exception

闲鱼技术团队于2018年上半年率先引入了Flutter技术实现客户端开发,到目前为止成功改造并上线了复杂的商品详情和发布业务。随着flutter比重越来越多,我们开始大力治理flutter的exception,起初很长一段时间内闲鱼内flutter的exception率一直在千分之几左右。经过我们的整理和解决,解决了90%以上的flutter exception。

我们对exception进行了归类,大头主要分为两大类,这两大类堆栈数量很多,占到整体90%左右:

第一大类的堆栈都指向了setstate

 
   
   
 
  1. #0      State.setState (package:flutter/src/widgets/framework.dart:1141)

  2. #1      _DetailCommentWidgetState.replyInput.<anonymous closure>.<anonymous closure> (package:fwn_idlefish/biz/item_detail/fx_detail_comment.dart:479)

  3. #2      FXMtopReq.sendReq.<anonymous closure> (package:fwn_idlefish/common_lib/network/src/mtop_req.dart:32)

  4. #3      NetService.requestWithModel.<anonymous closure> (package:fwn_idlefish/common_lib/network/src/net_service.dart:58)

  5. #4      _rootRunUnary (dart:async/zone.dart:1132)

  6. #5      _CustomZone.runUnary (dart:async/zone.dart:1029)

  7. #6      _FutureListener.handleValue (dart:async/future_impl.dart:129)

第二大类堆栈都与buildContext相关

 
   
   
 
  1. #0      Navigator.of (package:flutter/src/widgets/navigator.dart:1270)

  2. #1      Navigator.pop (package:flutter/src/widgets/navigator.dart:1166)

  3. #2      UploadProgressDialog.hide (package:fwn_idlefish/biz/publish/upload_progress_dialog.dart:35)

  4. #3      PublishSubmitReducer.doPost.<anonymous closure> (package:fwn_idlefish/biz/publish/reducers/publish_submit_reducer.dart:418)

  5. <asynchronous suspension>

  6. #4      FXMtopReq.sendReq.<anonymous closure> (package:fwn_idlefish/common_lib/network/src/mtop_req.dart:32)

  7. #5      NetService.requestWithModel.<anonymous closure> (package:fwn_idlefish/common_lib/network/src/net_service.dart:58)

  8. #6      _rootRunUnary (dart:async/zone.dart:1132)

  9. #7      _CustomZone.runUnary (dart:async/zone.dart:1029)

第一类明显与element和sate的生命周期有关。第二类与buildContext有关。

buildContext是什么?

下面是一段state中获取buildContext的实现

 
   
   
 
  1. Element get _currentElement => _registry[this];

  2. BuildContext get currentContext => _currentElement;

很明显buildContext其实就是element实例。buildContext是一个接口,element是buildContext的具体实现。所以上面的exception都指向了flutter element和state的生命周期。

Flutter Exception降到万分之几的秘密
Flutter 生命周期

state生命周期

Flutter Exception降到万分之几的秘密

element与state生命周期

element是由widget createElement所创建。state的生命周期状态由element调用触发。

Flutter Exception降到万分之几的秘密

最核心的是在new elment的时候element的state的双向绑定正式建立。在umount的时候element和state的双向绑定断开。

activity生命周期与state关系

flutter提供WidgetsBindingObserver给开发者来监听AppLifecycleState。 AppLifecycleState有4种状态:

 
   
   
 
  1. 1.resumed

  2. 界面可见,比如应用从后台到前台


  3. 2.inactive

  4. 页面退到后台或者弹出dialog等情况下

  5. 这种状态下接收不到很任何用户输入,但是还会有drawframe的回调


  6. 3.paused

  7. 应用挂起,比如退到后台。进入这种状态代表不在有任何drawframe的回调


  8. 4.suspending

  9. ios中没用,puased之后进入的状态,进入这种状态代表不在有任何drawframe的回调

看下android生命周期和appLifecycleState、state关系,

1.创建

Flutter Exception降到万分之几的秘密

2.按home键退到后台

Flutter Exception降到万分之几的秘密

3.从后台回到前台

Flutter Exception降到万分之几的秘密

4.back键退出当前页面(route pop)

Flutter Exception降到万分之几的秘密

5.back键退出应用

Flutter Exception降到万分之几的秘密

Flutter Exception降到万分之几的秘密
常见的exception例子

工程开发中容易忽略state的dispose状态

看一段例子:

Flutter Exception降到万分之几的秘密

这个例子可能会在某些情况下excetion。

在state dispose后,element会和state断开相互引用,如果在这个时候开发者去拿element的位置信息或者调用setstate 刷新布局时就会报异常。

最常见的是在一些timer、animate、网络请求等异步逻辑后调用setstate导致的excetion。安全的做法是在调用setstate前判断一下state是否是mounted状态。如下:

Flutter Exception降到万分之几的秘密

buildContext使用错误

看一段错误使用buildcontext例子:

Flutter Exception降到万分之几的秘密

上面的错误在于在跨堆栈使用了buildcontext。由于outcontext的生命周期与buttomcontext不一致,在弹出bottomsheet的时候outcontext可以已经处于umount或者deactivite。上面例子正确的做法是使用bottomcontext获取focusScopeNode。

我们在跨堆栈传递参数(如bottomsheet、dialog、alert、processdialog等)场景时特别要注意buildcontext的使用。

参考

https://github.com/flutter/flutter

https://flutter.io/docs


关注二维码,前瞻技术尽在掌握


以上是关于Flutter Exception降到万分之几的秘密的主要内容,如果未能解决你的问题,请参考以下文章

MySQL百分比显示和显示前百分之几的方法

MySQL百分比显示和显示前百分之几的方法

MySQL百分比显示和显示前百分之几的方法

微生物基因序列对比差异大于多少可判定为不同种属?

轻运营下的商业化之路

Flutter Ras公钥加密成功私钥解密失败:Unsupported block type for private key