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/f15cd2ed6ec0

public 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

更多相关文章

  1. Android中的内存溢出和内存泄漏问题
  2. android Cache——webview的缓存处理
  3. Android:这是一份全面&详细的 热修复 学习指南
  4. android动态加载ClassLoader机制
  5. Android中如何把bitmap存成BMP格式的图片
  6. android使用.9,png图片作为背景的问题
  7. android UI之Shape详解_GradientDrawable
  8. Android(安卓)ListView中复杂数据流的高效渲染
  9. Android(安卓)LazyList 从网络获取图片并缓存

随机推荐

  1. Android属性之build.prop生成过程分析
  2. Android(安卓)模仿QQ风格的 UI
  3. android 研究笔记
  4. 为什么Android没有iOS顺滑zz
  5. 关于android应用程序的入口
  6. android在list view中如何action的实现
  7. [Android] 获取Android设备的唯一识别码|
  8. 大话企业级android读书笔记(二)
  9. Android(安卓)ImageButton简介
  10. Android(安卓)基于TCP/IP的Socket通信