Im-Kevin / cool_ui

用flutter实现一些我认为好看的UI控件,有Popover,仿Weui的Toast,自定义键盘
Apache License 2.0
460 stars 74 forks source link

IOS14出现闪退 #58

Closed yangruiFkm closed 3 years ago

yangruiFkm commented 4 years ago

在IOS14正式版系统下,CupertinoPopoverButton组件点击后出现App闪退

issue-label-bot[bot] commented 4 years ago

Issue-Label Bot is automatically applying the label bug to this issue, with a confidence of 0.64. Please mark this comment with :thumbsup: or :thumbsdown: to give our bot feedback!

Links: app homepage, dashboard and code for this bot.

Im-Kevin commented 4 years ago

有错误日志吗

yangruiFkm commented 4 years ago

有错误日志吗 在xcode上看,会不断触发这个 io.flutter.1.raster (8): EXC_BREAKPOINT (code=1, subcode=0x1b4eb0c54) 在vscode上调试flutter,没有看到报错信息,直接crash

yangruiFkm commented 4 years ago

有错误日志吗 请问,能排查到问题吗?现在IOS14用户越来越多了,cool_ui非常棒,我们有5个核心功能依赖,如果解决不了,我们就只能换个组件了

Im-Kevin commented 4 years ago

我暂时比较忙,没有时间去排查

Im-Kevin commented 4 years ago

但是我猜测不是控件的问题,因为CupertinoPopoverButton是纯dart开发的,所以理论上不会引起闪退,只有机会引起报错

Im-Kevin commented 4 years ago

还有你能给下Tap后的代码看看吗,有可能是Tap后的某部分代码导致的

yangruiFkm commented 4 years ago

还有你能给下Tap后的代码看看吗,有可能是Tap后的某部分代码导致的

使用到CupertinoPopoverButton组件的场景有五个地方,有四处是没有定义onTap,有一处就只有一行return widget.disabled; 五处都可以稳定复现崩溃,我们之前也没有出现过纯dart组件引发的崩溃,一般只是会白屏。 下面是其中一处的写法:

@override Widget build(BuildContext context) { return CupertinoPopoverButton( child: Container( height: 40.rem, padding: EdgeInsets.fromLTRB(6.rem, 0, 6.rem, 0), child: Icon( Iconfont.level, color: levelColors[widget.selectedLevel ?? 0], size: 18.rem, ), ), barrierColor: Color.fromRGBO(0, 0, 0, .2), popoverBuild: (context) => Container( padding: EdgeInsets.fromLTRB(0, 12.rem, 0, 12.rem), child: CupertinoPopoverMenuList( children: levelValues.map((level) => getLevelItem(level)).toList(), ), ), popoverWidth: 80.rem, popoverHeight: 150.rem, ); }

Im-Kevin commented 4 years ago

我这边在iOS14使用未发现有这个问题

Im-Kevin commented 4 years ago

你可以clone demo运行看看

Im-Kevin commented 4 years ago

还有会不会是getLevelItem这里面的东西的问题,排查一下里面是否有引用原生控件或者原生代码

Im-Kevin commented 4 years ago

估计是有Widget引用了原生代码,你试着将其替换成最简单的Text试一下

yangruiFkm commented 4 years ago

估计是有Widget引用了原生代码,你试着将其替换成最简单的Text试一下

好的,我试一试

yangruiFkm commented 4 years ago

估计是有Widget引用了原生代码,你试着将其替换成最简单的Text试一下

刚刚尝试了把CupertinoPopoverMenuItem、CupertinoPopoverButton和CupertinoPopoverMenuList里面所有child都换成了Text('测试'),还是会在打开下拉窗口,看到mock数据之后,大概0.5秒App会crash

Im-Kevin commented 4 years ago

看mock数据?这个跟这里有什么关系吗

yangruiFkm commented 4 years ago

看mock数据?这个跟这里有什么关系吗

没,我的意思是,我把CupertinoPopoverMenuList里面的child都改成了Text('测试')之后,点击CupertinoPopoverButton,再看到了一排”测试“之后,就crash了,说明渲染widget没有受到影响,是渲染出来以后,才crash的

Im-Kevin commented 4 years ago

https://github.com/flutter/flutter/issues/60424 你可以看看这个

yangruiFkm commented 4 years ago

flutter/flutter#60424 你可以看看这个

这个我们关注过,我们原本在IOS14系统下进入App任何操作都会crash的,后来flutter官方宣布了解决方案,升级到了flutter的1.22.0-12.1.pre-beta版本之后,只有cool_ui的组件会带来crash,其他所有功能都不会crash了,才来看看这边有没有解决方案的

Im-Kevin commented 4 years ago

你试下我的demo会吗

yangruiFkm commented 4 years ago

你试下我的demo会吗

demo是指这个git项目的example文件夹下的flutter应用吗?

Im-Kevin commented 4 years ago

是的

Im-Kevin commented 4 years ago

请问现在怎么样了

yangruiFkm commented 4 years ago

请问现在怎么样了

../lib/dialogs/weui_toast.dart:207:29: Error: The argument type 'bool Function(bool)' can't be assigned to the parameter type 'bool Function(bool, RouteInfo)'.

本地启动example项目,因为我用的flutter版本比较高,有一个方法的参数应该是flutter高版本改过了,所以报错了

yangruiFkm commented 4 years ago

我把两处报错的方法调用都注释了,能打包并启动起来了。 debug模式和release模式,的确都不会闪退。

yangruiFkm commented 4 years ago

但是我把example里面CupertinoPopoverButton组件的代码,原封不动拷贝到我们的项目中,点击按钮必现crash,通过调试,在cupertino_popover.dart的第二次执行第73行语句“return FadeTransition“ 后会crash。 如果在这之前return了,不执行这个,就不会crash

lanistor commented 4 years ago

@Im-Kevin 我们也遇到了这个问题,demo可以run起来(flutter 1.22版本下需要加上dependency_overrides: back_button_interceptor: '4.2.2'),但是放在项目里,就会crash,flutter没有报错信息,xcode报错信息也很简单:

(6676,0x16baaf000) malloc: Incorrect checksum for freed object 0x1181c8800: probably modified after being freed.
Corrupt value: 0x2020227070612e

经过多次测试,大概定位到问题的范围是在_CupertionPopoverContext这个类,如果不使用_CupertionPopoverContext(比如下面的代码)就不会有问题,当然界面就丑陋了很多,猜测是绘制过程的问题,但是performLayout和paint方法都可以完整执行完成,异常是在这两个方法执行之后。

class CupertinoPopoverState extends State<CupertinoPopover>
    with TickerProviderStateMixin {
  static const double _arrowWidth = 12.0;
  static const double _arrowHeight = 8.0;

//  AnimationController animation;

  /// 是否箭头向上
  bool isArrowUp;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        _CupertionPopoverPosition(
          attachRect: widget.attachRect,
          scale: widget.doubleAnimation,
          constraints: widget.constraints,
          direction: widget.direction,
          child: Material(type: MaterialType.transparency, child: widget.child),
          // child: _CupertionPopoverContext(
          //   attachRect: widget.attachRect,
          //   scale: widget.doubleAnimation,
          //   radius: widget.radius,
          //   color: widget.color,
          //   boxShadow: widget.boxShadow,
          //   direction: widget.direction,
          //   child:
          //       Material(type: MaterialType.transparency, child: widget.child),
          // ),
        )
      ],
    );
  }
}

实在费解,主要是cool_ui的demo复现不出来问题,但是在项目里就有问题。

Im-Kevin commented 4 years ago

能否把你们引用的第三方库列一下,我猜测可能和其他库冲突了

Im-Kevin commented 4 years ago

还有debug模式下是否正常

lanistor commented 4 years ago

Debug模式也会出问题,下面是我们的pubspec.yaml:

environment:
  sdk: ">=2.6.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  mobx: ^1.2.1
  flutter_mobx: ^1.1.0
  sembast: ^2.4.7
  path_provider: ^1.6.5
  path: ^1.6.4
  crypto: ^2.1.3
  encrypt: ^4.0.3
  i18n: ^1.1.0
  flutter_slidable: ^0.5.4
  http: ^0.12.0+2
  flutter_local_notifications: ^1.2.0+3
  flutter_app_badger: ^1.1.2
  background_fetch: ^0.5.4
  date_format: ^1.0.8
  cool_ui: ^0.6.3
  flutter_flexible_toast: ^0.1.4
  oktoast: ^2.3.2
  device_info: ^0.4.1
  package_info: ^0.4.0
  url_launcher: ^5.4.2
  firebase_analytics: ^5.0.11
  lunar_calendar_converter: 1.0.4+1
  charts_flutter: ^0.9.0
  qr_flutter: ^3.2.0
  esys_flutter_share: ^1.0.2
  flutter_vibrate: ^1.0.0
  flutter_typeahead: ^1.8.1
  simple_tooltip: ^0.1.8
  permission_handler: 5.0.1+1
  advertising_id: ^1.0.0
  video_player: 0.10.12+3
  flick_video_player: ^0.1.1
  gallery_saver: ^2.0.1
  uni_links: ^0.4.0
dev_dependencies:
  flutter_test:
    sdk: flutter
  json_serializable: ^3.4.1
  mobx_codegen: ^1.0.2
  build_runner: ^1.10.2
Im-Kevin commented 4 years ago

debug 模式能不能帮我看看是具体哪一行代码导致的

lanistor commented 4 years ago

@Im-Kevin 能调试到的代码都执行完成没有报错。一直在尝试做一个最简易的demo可以复现这个问题,没能成功。 而且发现了一个更诡异的现象:改了bundleId就可以正确执行了。 我猜测可能是缓存引起的问题,但是用flutter命令清空缓存并没有效果,而且实在想不通,为什么只有这个插件有问题。

Im-Kevin commented 4 years ago

@yangruiFkm 你试着重新创建ios文件夹看看

Im-Kevin commented 4 years ago

https://github.com/flutter/flutter/issues/66241 可以参照这个

lanistor commented 4 years ago

@Im-Kevin 已经解决,感谢。不是cool_ui的问题,应该是flutter的问题,将Product Name从中文改成英文就可以了。

heartbeat986 commented 3 years ago

@Im-Kevin 已经解决,感谢。不是cool_ui的问题,应该是flutter的问题,将Product Name从中文改成英文就可以了。

赞,改成英文就解决了