发生场景
接受服务器数据,在控件上重新演示播放客户端的动作,并添加特效
播放烟花效果
演示客户端的动作,使用Canvas绘制Path;Path通过服务器传过来的点的坐标,按一定时间逐个绘制点就能完成动画的效果,达到重现动作的效果
在根据点绘制想的过程,需要加上一个特效;特效是播放gif,并让gif在一定时间之后消失
问题
-
在绘制数量较大的时候,内存容易oom
-
有时候在绘制的时候,会突然崩溃
-
绘制速度过快,会丢失部分绘制过程
解决过程
问题3的解决过程
在绘制快速的时候,查看了服务器发送的数据是否和绘制过程数据一致;结果:数据一致
判断:
应该是android在一次性接受过多数据的时候,漏写入了数据
继续检查接收到数据,是怎么写入的
发现:
在接收到数据后,需要做json解析;这个点,暂时没考虑
继续下去发现,只有一个二维数组在接受数据
考虑:
一个二维数组在接受两个数据的时候,会是什么情况
情况不明;考虑到现在使用情况是频繁的写入,读取,没有查看的操作
使用LinkedList,一边可以直接写,一边直接poll出来,无需考虑其他
使用LinkedList优势:插入的时候,不会新建列表;这里无需这个功能;取出的时候,无需考虑index
劣势:查询特别不方便,要遍历整个列表【但是这里不要这个功能
问题2是偶发性的,所以没特意注意;结果在解决问题1的时候,顺带就解决了
问题1的解决过程
考虑到gif耗性能,尝试使用canvas来手动绘制,结果后面成功绘制了相似的动画效果,但是无法使用到绘制复现的过程;
请教外援
结果:
回应,使用gif是可以实现特效的;特效是在短时间内绘制的,之后可以回收使用过的内存
使用canvas也可以绘制;但是耗时,又要重新做别人完成过的内容,不合算;暂时抛弃
转头继续使用gif解决问题
使用工具android profile来查看运行过程中的内存使用情况
发现演示设备的性能低于开发设备,演示设备在使用内存240+M的内存就会oom,开发设备使用内存280M都很正常使用
测试回收gif的代码;发现并没有什么大的效果;原来的很多代码其实对于内存的回收,并没有作用
查看代码,发现在复现绘制路线的时候,使用了for循环;在这个时候如果还没有绘制却将所有数据都放在了内存,就相当于复制了一边数据;于是修改成了递归的方式,降低了循环,并使用view的postDelay方式在使用的时候再继续递归下一次任务,内存确实降低了很多;但是最后的内存还是很多;降低的只是过程中的内存
修改gif加载过程;使用对象池来管理已经加载过的gif对象,再gif消失的时候,直接将GifDrawable放入对象池,后面新的路径,可以直接从对象池中获取gif对象;
队列使用:
考虑数据结构需要在频繁写入、读取的过程不能重新新建列表;新建列表速度太慢了
AI建议:
使用双端队列或者优先队列
这里使用了双端队列;情况改成了:频繁的写入、取出;写入到第一个,取出总是取最后一个;
这样可以保证:
-
没消息的时候,数组内不会有数据
-
接受的消息,在复现的时候,顺序不会错
烟花的gif,因为烟花比较少的原因,手点击比较,慢,所以考虑使用原型模式;
结果:
成功得到烟花的GifDrawable,但是不能recycle,会报错;这时候发现,原来问题2就是使用了recycle方法,导致程序崩溃;这个方法直接弃用;因为这里要复用GifDrawable,不能recycle
发现recycle必须在存放gif的view不可见的时候,才可以正常调用;
而且就算使用克隆方法克隆出了新的GifDrawable,但是一旦recycle,后面就无法克隆了;
这个方法直接霸气不用;
直接克隆后,发现成功展示了烟花;结果烟花模糊了;
发现是程序没退出,Glide的内存保存了前面的烟花,复制出来继续播放;
关闭Glide的缓存功能;这里没有使用这个功能
成功展示烟花;但是克隆出来的烟花,有问题:
烟花消失后,后面克隆的烟花,又把消失的烟花显示出来;而且动作一致
尝试别的方式克隆;依然没得到解决;直接采用上面的对象池技术;再来一次
成功解决;但是
烟花需要完整的播放完毕动画,才能给其他控件复用;所以必须要等烟花结束再回收复用
结果,回收复用的时候,发现复用的烟花,不是从最开始的时候播放烟花
使用Glide想得到烟花gif的时间长度,没成功
使用其他软件查看gif时间,设置进去,发现时间不对;应该是有程序的运行时间,或者这个时间就是不对的
果断放弃了Glide;使用了android-gif-drawable
成功获取gif时间,在播放结束的时候,reset了一下,再回收;再次展示;完美解决
查看gif大小是56k,通过gif编辑,缩小到16k;效果差不多;但是加载gif的内存肯定减少的
解决结果
问题3解决,在测试的时候,就算很快的用手绘制,也能正常复现,没有出现丢失过程的现象
问题1解决,运行一段时间后,内存不会增长太快,就是开始一直创建对象的时候会吃内存;但是你一开始就要展示这么多gif,一样的吃内存,我把内存都复用了,后面就是多了一个路径保存的内存,gif变成了内存中一直复用的一段内存;中间加载gif过程的内存,反而回收了
问题2解决,遇到偶发性的问题,别急;先解决其他的