Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.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
Java 什么';位图的这种inSampleSize计算方法有什么问题?内存不足_Java_Android_Bitmap - Fatal编程技术网

Java 什么';位图的这种inSampleSize计算方法有什么问题?内存不足

Java 什么';位图的这种inSampleSize计算方法有什么问题?内存不足,java,android,bitmap,Java,Android,Bitmap,在我的应用程序中,我反复浏览图像的URL,解码并将它们放入数组列表中 它们的大小可能差异很大,因此我使用inJustDecodeBounds=true选项进行“预解码”,以计算实际解码所需的inSampleSize值 请参阅下面我的方法,我希望它不太难理解。基本上,我的目标是一个大小类似的屏幕大小的设备 for (Element e: posts) { if (!e.id().equals("")) { //preparing decode options

在我的应用程序中,我反复浏览图像的URL,解码并将它们放入
数组列表中

它们的大小可能差异很大,因此我使用
inJustDecodeBounds=true
选项进行“预解码”,以计算实际解码所需的
inSampleSize

请参阅下面我的方法,我希望它不太难理解。基本上,我的目标是一个大小类似的屏幕大小的设备

for (Element e: posts) {
    if (!e.id().equals("")) {
        //preparing decode
        options = new BitmapFactory.Options();
        input = new URL(e.url).openStream();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(input, null, options);
        input.close();

        //setting inSampleSize if necessary
        int picPixels = options.outWidth * options.outHeight;
        int picScreenRatio = picPixels / screenPixels;
        if (picScreenRatio > 1) {
            int sampleSize = picScreenRatio % 2 == 0 ? picScreenRatio : picScreenRatio + 1;
            options.inSampleSize = sampleSize;
        }

        //actual decode
        input = new URL(e.url).openStream();
        options.inJustDecodeBounds = false;
        Bitmap pic = BitmapFactory.decodeStream(input, null, options);
        input.close();

        picList.add(pic);
    }
}
用于计算屏幕像素的代码:

Display display = getWindowManager().getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int screenPixels = screenSize.x * screenSize.y;
我用
java.lang.OutOfMemoryError
浏览了大约60张图片,大约40个应用程序崩溃

据我所知,使用
inJustDecodeBounds=true
没有分配内存,如果我的方法是正确的(我相信是正确的),非常大的图像在采样时会变得非常大,所以我不知道会出现什么问题


非常感谢您的建议。

样本大小必须是二的幂。从文件中:

如果设置为大于1的值,则请求解码器对原始数据进行二次采样 图像,返回较小的图像以节省内存。样本量为 任一维中对应于单个像素的像素数 解码位图中的像素。例如,inSampleSize==4返回一个 图像的宽度/高度为原稿的1/4,宽度/高度为原稿的1/16
像素数。任何值无论您使用inSampleSize,您都无法轻松地在内存中保存与屏幕一样大的60个位图

假设使用全高清屏幕,您可以获得大约1920*1080*60*4个字节

这大约是500 MB的数据。 您需要以某种方式更改位图加载逻辑

作为回答,你们可以找出你们能用多少内存来计算。它因不同的设备而不同


但要尽可能提高应用程序的内存利用率。

在Android上进行图像处理是出了名的困难。我建议您使用已建立的映像管理库,如:

他们文档中的一个示例:

Fresco的抽屉会为您显示占位符,直到图像加载完毕,并在图像到达时自动显示给您。当图像离开屏幕时,它会自动释放其内存

此外:

使用Fresco的应用程序甚至可以在低端设备上运行,而无需不断努力控制图像内存占用


我很确定这就是问题所在,不知道为什么我没有想到这一点。非常感谢。
    int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }

        return (int) n;
    }