在使用BitmapFactory.decodeStream解析is时,在is不为null的情况下BitmapFactory.decodeStream返回null。
异常如下:
代码如下:
private void obtainStyledAttr(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GifImageView, defStyleAttr, 0);
int resId = getIdentifier(a);
if (resId != 0) {
// 当资源id不等于0时,就去获取该资源的流
InputStream is = getResources().openRawResource(resId);
// 使用Movie类对流进行解码
mMovie = Movie.decodeStream(is);
//mMovie不等null说明这是一个GIF图片
if (mMovie != null) {
//是否自动播放
isAutoPlay = a.getBoolean(R.styleable.GifImageView_auto_play, false);
/**
* 获取gif图片大小
*/
Bitmap bitmap = BitmapFactory.decodeStream(is);
bitmapSize = new BitmapSize(bitmap.getWidth(), bitmap.getHeight());
bitmap.recycle();
}
}
a.recycle();
}
异常原因:
decodeStream调用了两次
- Movie类先对is进行了解码,代码如下:
// 使用Movie类对流进行解码
mMovie = Movie.decodeStream(is);
- 然后BitmapFactory又对is进行了解码,代码如下:
Bitmap bitmap = BitmapFactory.decodeStream(is);
第一次decodeStream时已经操作过inputstream了,这时候流的操作位置已经移动了,如果再次decodeStream则不是从流的起始位置解析,所以无法解析出Bitmap对象。
解决方法:
只需要在再次解码之前使流读写位置恢复为起始位置即可,代码如下:
private void obtainStyledAttr(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GifImageView, defStyleAttr, 0);
int resId = getIdentifier(a);
if (resId != 0) {
// 当资源id不等于0时,就去获取该资源的流
InputStream is = getResources().openRawResource(resId);
// 使用Movie类对流进行解码
mMovie = Movie.decodeStream(is);
//mMovie不等null说明这是一个GIF图片
if (mMovie != null) {
//是否自动播放
isAutoPlay = a.getBoolean(R.styleable.GifImageView_auto_play, false);
/**
* 获取gif图片大小
*/
try {
is.reset();
Bitmap bitmap = BitmapFactory.decodeStream(is);
bitmapSize = new BitmapSize(bitmap.getWidth(), bitmap.getHeight());
bitmap.recycle();
} catch (Exception e) {
Log.e("yushan", "" + e);
}
}
}
a.recycle();
}
参考链接:
https://blog.youkuaiyun.com/maxwell_nc/article/details/49081105