11月08, 2020

一个方案提升Flutter内存利用率

背景

我们闲鱼使用的图片方案是自研的外接纹理方案:

  • Android侧创建SurfaceTexture,通过FlutterJNI注册到Flutter engine里,最后返回texture id给Flutter应用层,应用层使用Texture Widget和textue id去显示图片纹理。
  • 纹理数据则是在Android侧,通过OpenGL将图片纹理写入到SurfaceTexture,然后通过Flutter engine里的共享内存,将纹理数据传入到应用层,最终交给Skia渲染。

这里面存在的问题: Flutter应用层的纹理数据没有缓存,每次都需要重新将Bitmap数据渲染成纹理,再交给Flutter应用层使用。Native图片加载会内存缓存,Flutter自身提供的图片库也存在缓存,这2个缓存相互隔离,占用很大的内存空间。而且Flutter图片缓存基本都是存放的本地资源图,而我们Flutter页面上大部分其实都是网络下载的外接纹理图片,导致缓存资源利用率很低。

分析

针对上述的3个问题,我们先抛开技术实现,假设下要解决这3个问题,最理想的一个解决方案是什么:

  • 纹理没有缓存,那我们在应用层增加一个纹理的内存缓存就解决了。
  • 当上层的应用层已经缓存纹理,那Native侧的Bitmap的内存缓存也可以被去掉,只保留图片资源的磁盘缓存。
  • 整个App的内存缓存,只有纹理缓存,Flutter的ImageCache缓存,为了避免内存资源的浪费,将这2个缓存合成一个

所以最理想的解决方案:整个App内只存在一个内存缓存,并且它既能缓存纹理,也能缓存Flutter的Image Widget加载的图片数据。

解决方案

ImageCache是官方提供的,我们没办法去掉,而且闲鱼App里也有一些地方使用Image Widget。现在解决方案就变成: 将纹理数据也放到ImageCache里缓存。使用纹理时,先从imageCache里取。

点击查看原文>

本文链接:https://blog.jnliok.com/post/4t9HrwJFvRh41X2328Gy.html

-- EOF --

Comments