6

我运行了颤振的插件image_picker示例。

当我从画廊中一张一张地挑选图像时,内存不断增加。理想情况下,memory should jump back因为它at most select one image在此示例应用程序中。

在此处输入图像描述

class _MyHomePageState extends State<MyHomePage> {
  File _imageFile;              <-- this one keep the file of selected image.
  dynamic _pickImageError;
  bool isVideo = false;
  VideoPlayerController _controller;
  String _retrieveDataError;

  void _onImageButtonPressed(ImageSource source) async {
    ...
    try {
      _imageFile = await ImagePicker.pickImage(source: source);  <--- how to set value
      setState(() {});
    } catch (e) {
      _pickImageError = e;
    }
    ...
  }

  @override
  Widget build(BuildContext context) {
    ...
    Image.file(_imageFile);   <-- how to use it to display UI.
    ...
  }
}

我的问题是如何dispose the resource使用File

4

2 回答 2

4

简单地选择 aFile不会影响内存,因为 aFile只是一个引用,并不保存文件系统实体的实际字节。但是,从文件中创建Image一个文件会增加内存使用量,因为它Image保存了它引用的所有字节File(一旦它读取了所有字节)。

根据您迄今为止分享的内容,我们无法判断这是否是代码问题。除非您一次维护对超过 1Image个的引用,否则您的应用将使用的最小内存应该反映该图像的大小。我说最低限度是因为垃圾收集不会过于激进,并且一旦您不再引用它就不会处理所有内容。只有当它知道它需要运行 GC 时,它才会运行 GC,这样应用程序不会被饿死并且操作系统也很高兴。我不知道这是否适用于 Flutter,但对于原生 Android,它还取决于制造商对 Android 操作系统的定制,它可以要求应用程序以各种频率运行 GC。

在内存分配清晰可见的用例中,只需在加载第二张图像后点击 GC 按钮即可。如果内存下降到与加载单个图像相同的水平,那么一切都很好。如果没有,您可能会在代码中的某处维护对这些图像的意外引用。

原生 Android 也有这个奇怪的东西(可能取决于版本/制造商) - 这在一些较旧的三星设备上最为明显 - 最后 4 个位图被缓存并且您无法清除该缓存,具体取决于您必须处理的位图,该缓存可能会占用应用程序的几乎所有可用内存,并且您最终会遇到 OOM 错误……希望 Flutter 不会这样做,或者允许开发人员控制它。

于 2019-09-20T09:43:35.227 回答
0

您可以使用maxHeightmaxWidth参数ImagePicker来加载调整大小的图像。

例如

var image = await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 600);

此外,如果您希望显示或保存到文件系统,您可以使用FlutterNativeImage插件(内部使用 ImagePicker 插件)获取图像路径和压缩值来压缩图像。

例如

var compressedImage = await FlutterNativeImage.compressImage(image.path, quality: 50);

参考:https ://github.com/btastic/flutter_native_image

于 2019-09-20T08:49:19.183 回答