Android带货直播系统如何优雅得加载大图,防止OOM

发布来源:云豹科技
发布人:云豹科技
2020-11-30 10:12:03

带货直播系统的很多场景中,会伴随着产品图片的放大,在遇到体积比较大的图片时,加载的时间和消耗的内存都会变长、变大,对于APP来说,很容易造成OOM,内存不够,对整个带货直播系统的使用体验会造成很大的下降今天就来讲一讲,如何优雅的加载体积大的图片。

在带货直播系统中,核心就是使用BitmapRegionDecoder(区域解码器)这个类。通过这个区域解码器,可以解码一个矩形区域的图像,有了这个我们就可以自定义一块矩形的区域,然后根据手势来移动矩形区域的位置就能慢慢看到整张图片了。

首先,初始化变量:

private void init(){
    mOptions = new BitmapFactory.Options();
    //滑动器
    mScroller = new Scroller(getContext());
    //所放器
    mMatrix = new Matrix();
    //手势识别
    mGestureDetector = new GestureDetector(getContext(),this);
    mScaleGestureDetector = new ScaleGestureDetector(getContext(),this);
}


BitmapFactory.Options用来配置Bitmap相关的参数,比如获取Bitmap的宽高,内存复用等参数。

 

GestureDetector用来识别双击事件,ScaleGestureDetector在带货直播系统中负责用来监听手指的缩放事件,都是系统提供的类,比较方便使用。

 

然后,设置需要加载的图片:

 public void setImage(InputStream is){
      mOptions.inJustDecodeBounds = true;
      BitmapFactory.decodeStream(is,null,mOptions);
      mImageWidth = mOptions.outWidth;
      mImageHeight = mOptions.outHeight;
      mOptions.inPreferredConfig = Bitmap.Config.RGB_565;
      mOptions.inJustDecodeBounds = false;
      try {
          //区域解码器
    mRegionDecoder = BitmapRegionDecoder.newInstance(is,false);
      } catch (IOException e) {
          e.printStackTrace();
      }
      requestLayout();
  }


设置需要加载的图片,无论图片放到哪里都可以拿到图片的一个输入流,所以参数使用输入流,通过BitmapFactory.Options拿到图片的真实宽高。

inPreferredConfig这个参数默认是Bitmap.Config.ARGB_8888,这里将它改成Bitmap.Config.RGB_565,去掉透明通道,可以减少一半的内存使用。最后初始化区域解码器BitmapRegionDecoder。

 

ARGB_8888就是由4个8位组成即32位, RGB_565就是R为5位,G为6位,B为5位共16位

接着,获取View的宽高,计算缩放值

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
     super.onSizeChanged(w, h, oldw, oldh);
     mViewWidth = w;
     mViewHeight = h;
     mRect.top = 0;
     mRect.left = 0;
     mRect.right = (int) mViewWidth;
     mRect.bottom = (int) mViewHeight;
     mScale = mViewWidth/mImageWidth;
     mCurrentScale = mScale;
  }


onSizeChanged方法在布局期间,当此视图的大小发生更改时,将调用此方法,第一次在onMeasure之后调用,可以方便的拿到View的宽高。

 

然后给我们带货直播系统自定义的矩形mRect的上下左右的边界赋值。一般情况下我们使用这个自定义的View显示大图,都是占满这个View,所以这里矩形初始大小就让它跟View一样大。

然后,就是绘制:

 @Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      if(mRegionDecoder == null){
          return;
      }
      //复用内存
      mOptions.inBitmap = mBitmap;
      mBitmap = mRegionDecoder.decodeRegion(mRect,mOptions);
      mMatrix.setScale(mCurrentScale,mCurrentScale);
      canvas.drawBitmap(mBitmap,mMatrix,null);
  }


通过区域解码器解码一个矩形的区域,返回一个Bitmap对象,然后通过canvas绘制Bitmap。需要注意mOptions.inBitmap = mBitmap;这个配置可以复用内存,保证内存的使用一直只是矩形的这块区域。

到这里,带货直播系统的运行就能绘制出一部分图片了,想要看全部的图片,需要手指拖动来看,这就需要处理各种事件了。当然,今天主要是介绍显示图片,至于滑动图片查看细节,这里就不详细介绍了。

声明:以上内容为云豹科技作者本人原创,未经作者本人同意,禁止转载,否则将追究相关法律责任www.yunbaokj.com

声明:
以上内容为云豹科技作者本人原创,未经作者本人同意,禁止转载,否则将追究相关法律责任