什么是OOM?
OOM,是OutOfMemory的缩写,翻译过来就是内存溢出。原因是:分配的太少;用的太多;用完没释放。
内存用完没有被释放–>内存泄漏
,大量的内存泄漏就导致OOM.
android 在没有利用框架去网络请求加载大图片,容易产生OOM.
java.lang.RuntimeException: Canvas: trying to draw too large(117608400bytes) bitmap.
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
避免OOM
思路:第一次读取图片,不写入内存,直接获取到图片的宽高,再通过用户设置的控件的宽高,和这個拉伸形式來计算期望的宽高,结合这四個参数來找出最适合的采样率,或者直接根据屏幕大小,控件大小來计算最佳采样率。
什么是采样率?
当采样率为1时,就相当于去下载高清无码原图,如果为3,那么采样率近似于原图的1/3,图片大小也会减小到原来的1/3.
如果我们把采样率写死的话–>BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 10;
容易得到下载的图片成AV画质,所以我们下面要学习动态计算采样率,下载图片:
public void getBigImage(View view) {
ImageView imageView = this.findViewById(R.id.image_container);
BitmapFactory.Options options = new BitmapFactory.Options();
//设置为true以后呢,不是真的载入到内存中,只是获取到图片的相关信息
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(),R.mipmap.test_pic,options);
int width = options.outWidth;
int height = options.outHeight;
int measuredWidth = imageView.getMeasuredWidth();
int measuredHeight = imageView.getMeasuredHeight();
Log.d(TAG,"width -- > " + width + " measure width -- > " + measuredWidth);
Log.d(TAG,"height -- > " + height + " measure height -- > " + measuredHeight);
int sampleSize;
if(width < measuredWidth || height < measuredHeight) {
sampleSize = 1;
} else {
int subHeight = width / measuredWidth;
int subWidth = height / measuredHeight;
sampleSize = subHeight > subWidth ? subHeight : subWidth ;
}
Log.d(TAG,"sampleSize -- > " + sampleSize);
options.inSampleSize = sampleSize;
//变成false了,真的存入内存
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.test_pic,options);
imageView.setImageBitmap(bitmap);
}
关于图片加载的思路可以去看Volley或okhttp的源码!!!
参考: 阳光沙滩——>拉大锯