Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android将drawable加载到ImageView中占用大量内存_Android_Performance_Memory_Drawable - Fatal编程技术网

Android将drawable加载到ImageView中占用大量内存

Android将drawable加载到ImageView中占用大量内存,android,performance,memory,drawable,Android,Performance,Memory,Drawable,我有个问题 我正在将9drawables动态加载到9imageview中。(drawables每次都不同)可绘制id存储在对象类中,因此当我加载此可绘制文件时,我使用imageView.setimagesource(myObject.getresourceid())将imagesource设置为imageView 一切都很好,但当加载9个Drawable时,我在Android内存监视器上看到分配内存达到80MB,我认为这是不正常的。。。(是吗?) 我尝试了不同的方法来解决它: 加载带有毕加索库

我有个问题

我正在将9
drawables
动态加载到9
imageview
中。(
drawables
每次都不同)可绘制id存储在对象类中,因此当我加载此可绘制文件时,我使用
imageView.setimagesource(myObject.getresourceid())将
imagesource
设置为
imageView
一切都很好,但当加载9个Drawable时,我在Android内存监视器上看到分配内存达到80MB,我认为这是不正常的。。。(是吗?)

我尝试了不同的方法来解决它:

  • 加载带有毕加索库的绘图表
  • 使用
    BitmapFactory.decoderessource
    创建位图,然后 在imageView上设置ImageBitmap
使用我尝试过的所有技术,它需要80MB的分配内存

我试着使用不同的图像分辨率,所以在ldpi(~30Ko/image)和xhdpi(~87Ko/image)中,它不会改变任何东西,因为每个加载的图像都需要大约5MB的分配内存

所以我的问题是:如何减少为这些图像分配的内存

提前谢谢,如果有必要,我可以提供部分代码

问候


注:
imageview
是在
onCreate()
方法中动态创建的。

这很正常,内存中最大的敌人是图像。还要注意的是,图像在内存中占用的空间比磁盘上要多。加载时间长也是正常的。解决方案是只加载所看到的大图像,并使用缓存下次更快地加载它们(您不需要再次减少采样)。下面是一篇文章,其中有一个示例项目:

根据图像的性质,这实际上是可以的。由于使用了压缩算法,现代图像的文件大小不一定与它在内存中的大小有关。在内存中,假定的小文件被扩展为实际的位图数据,这意味着RAM中占用的数据将多于sd卡/磁盘上的数据

然而,来源(以及图像)将有助于进一步分析


您还可以查看某个查看器中的图像,并尝试确定加载到该查看器时它占用了多少RAM。你可能会对这些图片的大小感到惊讶。这就是为什么主题严重依赖图像的UI如此消耗内存。

多亏了Bojan Kseneman的链接,我将分配的内存减少到了30Mb。我用这个:

imageView.setImageBitmap(Util.decodeSampledBitmapFromResource(getResources(), id, 150, 150));
Util是我的项目的一个实用类

通过这些方法:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


你是对的,但是drawables最多加载1倍,所以我认为没有必要将其保存在缓存中。。但是谢谢你的回答。你仍然可以减少样本,只取所需的数量。使用缓存避免每次都这样做也是个好主意。由于你的链接,我减少了分配的内存。但是为了以可接受的质量显示我的图像,它达到了大约60MB的RAM。是正确的还是太多了?我想没关系。您会发现,现在的结果会随着设备的分辨率而变化,分辨率越低,使用的内存就越少,因此较旧的设备将能够处理它。我很高兴你放弃了这个用法:)没关系!我现在保持在40MB以下!谢谢:)是的,这是真的,但多亏了博扬·克塞内曼的链接,我也许能找到解决办法。我将尝试设置位图的高度和宽度,因为实际上,大的可绘制图形是在小的imageView中加载的,所以这可能是解决方案。我现在就试试。加载缩小的图片而不是原始图片,你能分享代码吗?
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;
    }