Android面试系列文章2018之内存管理之Bitmap的加载篇
2018-02-26 21:44
351 查看
Android面试系列文章2018之内存管理之Bitmap的加载篇
1.recycle方法
Bitmap在Android中内存存储位置有两块:1.native区(C区):必须调用Bitmap对象的recycle()方法才能对该Bitmap对象C区的内存进行回收。注意的是recycle执行是不可逆的,注意谨慎调用。
2.Java区(自动回收)。
2.LRU(最近最少使用算法)
它是怎么实现的?你可以这么回答:它是一个泛型类,它内部是有一个LinkedHashMap集合,内部提供了一个get和put方法来完成缓存的添加和获取操作,当缓存满的时候,你再往里面添加新的缓存对象的时候,它就会调用trimToSize这个方法把旧的并且使用次数少的缓存对象移除掉,然后再添加新的缓存对象。3.计算inSampleSize
加载图片时应该加载合适尺寸,分辨率大小等的图片,不可能每个位置都去加载原图,所以我们需要计算出某些显示图片的地方最合适尺寸,分辨率等大小的图片,这需要对inSampleSize进行计算,才能让图片做出合适的调整。当然也为了避免OOM异常。https://www.jianshu.com/p/f15cd2ed6ec0public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int width = options.outWidth; final int height = options.outHeight; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { //计算图片高度和我们需要高度的最接近比例值 final int heightRatio = Math.round((float) height / (float) reqHeight); //宽度比例值 final int widthRatio = Math.round((float) width / (float) reqWidth); //取比例值中的较大值作为inSampleSize inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio; } return inSampleSize; }
inSampleSize的默认值和最小值为1(当小于1时,解码器将该值当做1来处理),且在大于1时,该值只能为2的幂(当不为2的幂时,解码器会取与该值最接近的2的幂)。例如,当inSampleSize为2时,一个20001000的图片,将被缩小为1000500,相应地,它的像素数和内存占用都被缩小为了原来的1/4:
4.缩略图
public static Bitmap getThumbnail(Uri uri,int size, Context context) throws Exception { InputStream input = context.getContentResolver().openInputStream(uri); //配置BitmapFactory.Options,inJustDecodeBounds设为true,以获取图片的宽高 BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); onlyBoundsOptions.inJustDecodeBounds = true; onlyBoundsOptions.inDither=true;//optional onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional //计算inSampleSize缩放比例 BitmapFactory.decodeStream(input, null, onlyBoundsOptions); input.close(); if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) return null; int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth; double ratio = (originalSize > size) ? (originalSize / size) : 1.0; //获取到缩放比例后,再次设置BitmapFactory.Options,获取图片缩略图 BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio); bitmapOptions.inDither=true;//optional bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional input = context.getContentResolver().openInputStream(uri); Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); input.close(); return bitmap; } /** * 将double的比例采用近似值的方式转为int * @param ratio * @return */ private static int getPowerOfTwoForSampleRatio(double ratio){ int k = Integer.highestOneBit((int)Math.floor(ratio)); if(k==0) return 1; else return k; }
总体思想是通过设置BitmapFactory.Options.inJustDecodeBounds设为true,先获取到图片的宽高而并不会生产Bitmap;再通过所需图片的最长边size来获取缩放比例inSampleSize的值;
然后获所需尺寸的图片。
https://www.jianshu.com/p/d30c5e7d266d
5.三级缓存
a.网路b.内存
c.本地
总体思想就是为用户节约流量,当你在加载一张图片时,首先先判断本地是否已经缓存了该图片,如果没有,那么就通过网络进行加载,从网络加载的图片首先会存在与内存当中,为了节约用户的流量,可以将这张图片保存至本地,当用户退出程序或者某个操作导致这张图片被回收了,当用户某个操作又再试图加载这张图片的时候,此时由于本地已经缓存下来了,所以直接从本地把图片加载到内存当中并显示给用户即可。具体如何实现请看以下链接:
http://blog.csdn.net/u012325403/article/details/50388889
相关文章推荐
- Android面试系列文章2018之内存管理之冷启动过优化篇
- Android面试系列文章2018之内存管理之UI卡顿篇
- Android面试系列文章2018之Java部分类加载器篇
- Android面试系列文章2018之ListView篇
- Android面试系列文章2018之内存管理篇
- Android面试系列文章2018之Android Studio目录结构篇
- Android面试系列文章2018之Android部分WebView篇
- Android面试系列文章2018之Android部分Handler机制篇
- Android面试系列文章2018之架构搭建之MVVM模式篇
- Android面试系列文章2018之进程保活篇
- Android面试系列文章2018之Java部分注解篇
- Android面试系列文章2018之Android插件化篇
- Android面试系列文章2018之Android部分之动画机制篇
- Android面试系列文章2018之Android部分View绘制机制篇
- Android面试系列文章2018之Android构建流程篇
- Android面试系列文章2018之实战经验部分之gradle篇
- Android面试系列文章2018之架构搭建之MVP模式篇
- Android面试系列文章2018之Android部分之自定义View篇
- Android面试系列文章2018之Android部分IntentService机制篇
- Android面试系列文章2018之实战经验部分之异步框架篇