【问题标题】:Set Android View background image efficiently gives java.lang.OutOfMemoryError设置 Android View 背景图像有效地给出 java.lang.OutOfMemoryError
【发布时间】:2015-10-18 11:48:01
【问题描述】:

在将背景图像设置为 Android 视图 (API 22) 的过程中,我遇到了一些问题。

我的图片是 1MB .jpeg 文件,4000x2672。

起初我尝试通过

android:background="@drawable/your_image"

方法,得到一个D/skia:---缩放位图分配失败错误。

然后我关注http://developer.android.com/training/displaying-bitmaps/load-bitmap.html,实现如下:

BitmapDecoder.java

(..omissis..)
public class BitmapDecoder {

    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(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);
}

}

SplasActivity.java(主要活动)

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    LinearLayout mL = (LinearLayout)findViewById(R.id.MainLayout);
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int width = size.x;
    int height = size.y;

    if (Build.VERSION.SDK_INT >= 16) {
        Drawable d = new BitmapDrawable(getResources(),
                BitmapDecoder.decodeSampledBitmapFromResource(getResources(),
                        R.drawable.andromeda,
                        1080,1920));
        mL.setBackground(d);
    }

    this.getSupportActionBar().hide();
}

我正在获取设备屏幕的 WxH,将 Drawable 资源调整为该大小,将生成的位图转换为 Drawable,将 Drawable 设置为视图背景。

但我总是得到

D/skia: --- 缩放位图分配失败
...
java.lang.OutOfMemoryError: 无法分配 684032012 字节分配,16777120 可用字节和 227MB 直到 OOM

错误。

我已经搜索了几个小时,但没有成功实施所有建议的技术。

附带说明,如果我将宽度和高度设置为一个非常小的值(例如 400x200),它就可以工作。但是,正如您可能想象的那样,这是不可行的。

你知道怎么解决吗?

【问题讨论】:

  • 您要为图像分配 684 MB 的空间吗?从 logcat 发布堆栈跟踪,calculateInSampleSize 返回什么?
  • 来自 logcat 的堆栈跟踪:pastebin.com/2nxTDjLb
  • calculateInSampleSize 返回 1,屏幕分辨率为 1440 x 2560 (Samsung Galaxy S6)
  • 把你的 jpeg 放到 res/drawable-nodpi 文件夹中看看会发生什么
  • 宾果游戏!这就是问题所在。将它放在 drawable 文件夹中使 Android 将其假定为 mdpi 可绘制对象,因此在将其传递给 decodeSampledBitmapFromResource 之前将其放大多次。谢谢。

标签: java android bitmap background drawable


【解决方案1】:

从你的数字来看,你已经把你的jpeg放在res/drawable文件夹中了,和res/drawable-mdpi一样,解决办法是把它放在res/drawable-nodpi文件夹里

【讨论】:

    【解决方案2】:

    我认为问题在于您以压缩的 jpeg 格式 (1MB) 评估图像大小,但是当您将其加载并操作到您的软件中时,它会以位图形式解压缩。

    如您提到的链接中所述: “... 较低分辨率的版本应该与显示它的 UI 组件的大小相匹配。具有较高分辨率的图像不会提供任何可见的好处,但仍会占用宝贵的内存并由于额外的动态而导致额外的性能开销缩放。 ..”

    您使用的是 4000x2672= 10688000 像素的图像,每个像素需要多个字节来编码颜色,因此分配了 684032012 个字节。

    我能给出的唯一建议是评估你想在哪个更大的屏幕上显示你的图像,检查它的定义并重新调整你的图像,以便最多匹配那个值。

    【讨论】:

    • 不一定,实际上我没有检查用于颜色编码的实际字节数是多少,这就是为什么我没有在回复中指定任何其他数值。无论如何,需要消耗一部分内存来重新缩放并将太大的图像适应小屏幕。我的目的只是表明图像比需要的大,而不是调查细节。
    • 这是罪魁祸首。实际使用的图片尺寸不是4000x2672。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 2020-02-09
    相关资源
    最近更新 更多