今天想往一个ImageView中添加一个图片,发生了如题的异常,最终ImageView加载图片失败。Google了几种解决方式。
第一种,解除限制:
Android 所有的渲染都是基于OpenGL的硬件加速,简单说就是硬件加速的时候,对图片的大小有限制。不同设备可能有不同的最大值。所以最粗暴的解决方式就是关闭硬件加速,在AndroidManifest文件中添加如下语句:
<application android:hardwareAccelerated="false">
第二种就是对原图进行一些缩放,使得图片符合设备的最大值:
mImageView = (ImageView) findViewById(R.id.iv_loading);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.loadingpicture);
Bitmap scaled = Bitmap.createScaledBitmap(bm, width, height, true);
其中R.drawable.loadingpicture
是我想要加载并预先存放在drawable文件夹下的图片资源。
前两行的代码都比较好理解,看一下第三行代码的源码:
/**
* Creates a new bitmap, scaled from an existing bitmap, when possible. If the
* specified width and height are the same as the current width and height of
* the source bitmap, the source bitmap is returned and no new bitmap is
* created.
*
* @param src The source bitmap.
* @param dstWidth The new bitmap's desired width.
* @param dstHeight The new bitmap's desired height.
* @param filter true if the source should be filtered.
* @return The new scaled bitmap or the source bitmap if no scaling is required.
* @throws IllegalArgumentException if width is <= 0, or height is <= 0
*/
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
boolean filter) {
Matrix m;
synchronized (Bitmap.class) {
// small pool of just 1 matrix
m = sScaleMatrix;
sScaleMatrix = null;
}
if (m == null) {
m = new Matrix();
}
final int width = src.getWidth();
final int height = src.getHeight();
final float sx = dstWidth / (float)width;
final float sy = dstHeight / (float)height;
m.setScale(sx, sy);
Bitmap b = Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
synchronized (Bitmap.class) {
// do we need to check for null? why not just assign everytime?
if (sScaleMatrix == null) {
sScaleMatrix = m;
}
}
return b;
}
重点关注注释部分,其中第二第三个参数,是缩放后的图片尺寸,我们只需要根据屏幕尺寸和原图长宽比以及OpenGL的限制调节即可,并且如果新的bitmap相对原图无缩放将会自动放上原图,防止浪费资源。
第三种情况比较特殊,主要原因是存放图片资源的文件夹选择不当。
举个例子,假设我有一张1280*727的图片,然后OpenGL的限制是2048*2048。在这种情况仍然可能发生如标题所述的异常。原因是,我把图片放置在未指定分辨率drawable的文件夹下了。然而Android默认未指定分辨率的drawable为mdpi,所以当我们的手机屏幕分辨率不同时,会自动扩大或缩小这些图片。正确的解决方式应该是新建一个drawable-nodpi文件夹下,并将图片资源放在这个文件夹下。