BitmapFactory.DecodeByteArray导致Grow Heap(frag case)
我正在开发Xamarin的Android应用程序。 我在从字节流生成图像时遇到问题。 BitmapFactory(这似乎是最流行的解决方案)正在造成巨大的分配问题 – Grow Heap。
ConnectToDb connect = new ConnectToDb (); byte[] arr = connect.SelectImgByte(3,"Thea"); BitmapFactory.Options options=new BitmapFactory.Options(); options.InJustDecodeBounds = true; bmp = BitmapFactory.DecodeByteArray (arr, 0, arr.Length/*,options*/); _imageView.SetImageBitmap (bmp);
以上是调用BitmapFactory.DecodeByteArray的方法。 它工作正常,显示图像。 但它很慢并导致这些“警告”。
Thread started: #6 [dalvikvm-heap] Grow heap (frag case) to 22.596MB for 1997584-byte allocation [Choreographer] Skipped 129 frames! The application may be doing too much work on its main thread. [dalvikvm-heap] Grow heap (frag case) to 20.755MB for 1997584-byte allocation [dalvikvm-heap] Grow heap (frag case) to 22.735MB for 1997584-byte allocation [dalvikvm-heap] Grow heap (frag case) to 24.710MB for 1997584-byte allocation
每次调用该方法时,都会出现Grow Heap错误。 正如您所看到的那样,我已将图像加载到imageview 4次。 所以,我想知道是否有人和我有同样的问题? 通过查看这里(以及其他地方)我试了好几个小时来解决问题,但我找不到解决方案。 请记住,我正在使用Xamarin编写应用程序(c#语言 – 使用Android库)。
对不起糟糕的链接,但我没有足够的信誉在这里上传图像:)
我看到的第一件事是你使用InJustDecodeBounds
,它通常用于获取图像的宽度和高度,如下所示:
var options = new BitmapFactory.Options { InJustDecodeBounds = true, }; using (var derp = BitmapFactory.DecodeResource(Resources, Resource.Id.myimage, options)) { } var imageHeight = options.OutHeight; var imageWidth = options.OutWidth;
这通常用于在缩小图像之前获得图像的宽高比,而不是将大图像加载到存储器中。
如果您查看有关在Xamarin文档中有效加载大位图的文档,您会发现它们只是用它来使用它。
然后他们确保在using
语句中加载Bitmap
并将其分配给ImageView
如下所示:
using(var bmp = DecodeBitmap(some args)) imageView.SetImageBitmap(bmp);
如果您之后不需要Bitmap
,可以在其上调用Recycle()
,告诉Java Runtime摆脱它:
using(var bmp = DecodeBitmap(some args)) { imageView.SetImageBitmap(bmp); bmp.Recycle(); }
所以你需要做类似的事情,可能还有你的byte
数组,因为它包含图像的所有像素。
因此,使用文档中的模式,您可以执行以下操作:
byte[] arr = connect.SelectImgByte(3,"Thea"); using(var bmp = DecodeSampledBitmapFromArray(arr, scaledWidth, scaledHeight)) { _imageView.SetImageBitmap(bmp); bmp.Recycle(); } public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image var height = (float)options.OutHeight; var width = (float)options.OutWidth; var inSampleSize = 1D; if (height > reqHeight || width > reqWidth) { inSampleSize = width > height ? height/reqHeight : width/reqWidth; } return (int) inSampleSize; } public static Bitmap DecodeSampledBitmapFromArray(byte[] pixels, int reqWidth, int reqHeight) { var options = new BitmapFactory.Options { InJustDecodeBounds = true, }; using (var dispose = BitmapFactory.DecodeResource(arr, 0, arr.Length, options)) { } // Calculate inSampleSize options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.InJustDecodeBounds = false; return BitmapFactory.DecodeResource(arr, 0, arr.Length, options); }
- Android相当于Windows Phone的Deployment.Current.Dispatcher.BeginInvoke?
- MvvmCross; 如何从另一个ViewModel RaisePropertyChange
- 在屏幕点读取像素颜色(有效)
- 如何在webview中下载文件..?
- 如何使用visual studio和xamarin关闭活动android
- 将位图保存到文件 – Xamarin,Monodroid
- Xamarin(Android)unit testing在Visual Studio 2017中
- 如何在xamarin android应用程序中使用动画?
- Scrollview监听器在Xamarin for Android中无效?