android加载大量位图导致堆急剧增长
我正在构建一个新闻应用程序,从url加载许多位图并在屏幕上显示它们。 每次我加载20张图片,当用户到达屏幕底部时,我会再加载20张图片。。 问题是每一页白色的20张图片占用大约15-20兆的堆内存,当我到达第3页时,它已经是60兆了。 我从android开发者那里读到了关于加载位图的内容,做了很多他们说的事情,但仍然面临着巨大的问题 这是我调用以加载新位图的代码:android加载大量位图导致堆急剧增长,android,bitmap,heap-memory,Android,Bitmap,Heap Memory,我正在构建一个新闻应用程序,从url加载许多位图并在屏幕上显示它们。 每次我加载20张图片,当用户到达屏幕底部时,我会再加载20张图片。。 问题是每一页白色的20张图片占用大约15-20兆的堆内存,当我到达第3页时,它已经是60兆了。 我从android开发者那里读到了关于加载位图的内容,做了很多他们说的事情,但仍然面临着巨大的问题 这是我调用以加载新位图的代码: public static Bitmap loadBitmap(String url, int width, int hight)
public static Bitmap loadBitmap(String url, int width, int hight) {
InputStream in = null;
BufferedOutputStream out = null;
int icWidth = width;
int picHight = hight;
try {
in = new BufferedInputStream(new URL(url).openStream(),
IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();
bitmap = decodeSampledBitmapFromResource(data, 0, width);
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
} catch (IOException e) {
Log.e(TAG, "Could not load Bitmap from: " + url);
} finally {
closeStream(in);
closeStream(out);
}
return bitmap;
}
public static void resycle() {
bitmap.recycle();
}
/**
* Closes the specified stream.
*
* @param stream
* The stream to close.
*/
private static void closeStream(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
android.util.Log.e(TAG, "Could not close stream", e);
}
}
}
/**
* Copy the content of the input stream into the output stream, using a
* temporary byte array buffer whose size is defined by
* {@link #IO_BUFFER_SIZE}.
*
* @param in
* The input stream to copy from.
* @param out
* The output stream to copy to.
* @throws IOException
* If any error occurs during the copy.
*/
private static void copy(InputStream in, OutputStream out)
throws IOException {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
public static Bitmap decodeSampledBitmapFromResource(byte[] data,
int width, int hight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, width, hight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
如何在保持小堆的同时加载大量图片?我可能发现了两个问题: 一,。下面的方法
public static Bitmap decodeSampledBitmapFromResource(byte[] data,
int width, int hight)
接受宽度和高度参数,但您使用
decodeSampledBitmapFromResource(data, 0, width);
所以基本上通过0作为要求的宽度,宽度作为要求的高度。这似乎不对
二,。您提到,您正在传递完整的表格宽度/高度作为每个图像的请求宽度/高度。您说每页加载20个,那么这不应该是一个表单元格的大小而不是整个表的大小吗
现在,你最多只能将它们缩小到全屏大小,即使在较小的设备上也会留下一个大图像。通过缩小它们,我准备好了。当我调用loadBitmap方法时,我会根据用户的屏幕大小发送位图url以及图片的宽度和高度。是的,你说得对,我的错。那么你最终的尺寸通常是多少呢?同样,它取决于用户的屏幕大小。。。我把桌子的宽度稍微调一调,然后屏幕的宽度是-20,高度是-20/1.5,这就是为什么我在我的问题中添加了“典型”。嘿,我在方法中添加了正确的宽度和高度。。谢谢你指出这一点。我只传递表格宽度作为参数,即我从宽度中剪切的高度。。宽度总是保持不变,所以我不认为这是一个问题…我认为更重要的问题是,你真的没有缩小到更像缩略图的大小。还是我弄错了?好吧,如果你这么说的话。看起来像是浪费资源。即使我把它缩小一点,我还是会有同样的问题。不是每20张图片获得20米堆,而是获得16米堆。。。当你播放它时,仍然需要大量的内存。。我的技术不对。。