1.问题描述:
一个聊天对话页面,由于对话框形状需要自定义,因此采用了
CustomPainter
来自定义绘制对话框。测试过程中发现在ipad mini
上不停地上下滚动对话框列表竟然出现了crash
,进一步测试发现连天过程中也会频繁出现crash
。
2.问题分析:
1.首先,对于crash我们想到的是会不会是某处空指针引起的。接着我们给可能出现空指针的调用全部添加了容错处理(
dart
语言只需在对象后面添加‘?’),处理完之后发现crash
依然存在(令人崩溃...)。2.排除了空指针因素后,我们继续猜测会不会是某个操作引起主线程阻塞导致
crash
。经过排查,页面中并无此情况。3.无计可施的情况下,我们在安卓手机上安装APP(之前一直都是在ios上测试)并进入聊天页进行测试,果然
crash
如期而遇。仔细分析log后我们发现,每次crash
之前必定有一次以上的system.gc()
。由此我们进一步猜测是否可能因为内存溢出导致的crash
,抓住这一条线索,我们在xcode
上进行了运行时内存观测。果不其然,每次crash
时APP
的内存占用相当高,最高逼近总内存的50%。由此可初步推断crash由于内存泄漏引起。
3.内存使用情况
优化前的内存使用情况 优化前的内存使用情况 优化前的内存使用情况 优化后的内存使用情况4.问题探究
通过打log我们终于找出了原因,导致内存泄漏的罪魁祸首便是
CustomPainter
的paint
函数被不停地回调,静止(不做任何手工交互)时次数一度达到上千次,这简直是噩梦。然后通过尝试, 将CustomPaint
的child
注释后再次运行后一切恢复了正常。检查child
我们发现里面除了一个动画(拥有静止态和播放态)和一切普通的Widget
外并无其他,因此尝试着将动画注释后,仍然运行正常。加入动画并播放后再次出香paint
被重复疯狂回调直至动画播放结束才停止回调。由此,我们断定出现内存泄漏的最终原因是动画播放导致
CustomPaint
的paint
函数返回回调,最终致使内存溢出从而APP发生Crash。
5.解决方法
6.心得体会
花了一天时间解决这个问题,真让人头大。初学flutter,遇到过不少一时难以解决的问题,不过好在方法总比问题多,只要肯用心去发现,没有解决不了的问题。