我正在开发中Xamarin的Android应用程序。我有从字节流生成图像的问题。 BitmapFactory(这似乎是最流行的解决方案),是造成巨大的分配问题 - 成长堆。
I am developing an Android app in Xamarin. I am having problems with generating an image from a bytestream. BitmapFactory (which seems to be the most popular solution), is causing huge allocation problems - 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.De codeByteArray的被调用的方法。它做工精细,显示图像。但它是缓慢的,并导致这些警告。
Above is the method where BitmapFactory.DecodeByteArray is being called. It works fine, the image is displayed. But it is slow and causes these "Warnings".
Thread started: <Thread Pool> #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
有关每次调用该方法,成长堆出现错误。正如你可以看到我已经加载的图像的ImageView的有4次。所以,我想知道如果任何人有同样的问题吗?我试过好几个小时来解决这个问题,通过寻找在这里(和其他地方),但我无法找到一个解决方案。请记住我写在Xamarin应用。(C#语言 - 采用Android库)
For everytime the method is called, Grow Heap error appears. As you can see i have loaded an image to an imageview 4 times there. So, i was wondering if anyone had the same problem as me? I tried for many hours to solve the problem, by looking in here (and else where) but i could not find a solution. Keep in mind i am writing the application in Xamarin (c# language - using Android library).
对不起,糟糕的链接,但我没有足够的名气上传图片来呢:)
Sorry for the lousy links, but i don't have enough cred to upload images here yet :)
我看到的第一件事情就是你用 InJustDe codeBounds
,这通常是用来获取像这样图像的宽度和高度:
First thing I see is that you use InJustDecodeBounds
, which usually is used to get the width and height of the image like so:
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;
此通常用于获得图像的高宽比,比例缩小,而不是加载巨大图像到存储器之前
This is generally used to get the aspect ratio of the image, before scaling it down, instead of loading a huge image into the memory.
如果你看看在有关装入大的位图的有效的Xamarin文档中,你会发现,他们使用它只是文档。
If you take a look at the docs about loading large bitmaps efficiently in the Xamarin documentation you will find that they use it for just that.
然后,他们要确保加载位图
在使用
语句,并将其分配给的ImageView
是这样的:
Then they make sure to load the Bitmap
in a using
statement and assign it to the ImageView
like this:
using(var bmp = DecodeBitmap(some args))
imageView.SetImageBitmap(bmp);
在这里您不需要情况下,位图
以后你可以叫回收站()
就可以了,这告诉Java Runtime,以摆脱它:
In cases where you don't need the Bitmap
afterwards you can call Recycle()
on it, which tells the Java Runtime to get rid of it:
using(var bmp = DecodeBitmap(some args)) {
imageView.SetImageBitmap(bmp);
bmp.Recycle();
}
所以,你需要做同样的事情,也可能与你的字节
阵列,因为它包含了图像的所有像素。
So you need to do something similar, probably also with your byte
array as it contains all the pixels for the image.
因此,使用中的文档模式,你可以做这样的事情:
So using the pattern in the docs you could do something like this:
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应用程序在前台(API 21)你的、前台、应用程序、Andr
下一篇:BroadcastReceiver的BOOT_COMPLETED后不工作工作、BroadcastReceiver、BOOT_COMPLETED