【Glide 】框架在内存使用方面的优化

BitmapPool

接口定义

public interface BitmapPool {

  long getMaxSize();

  void setSizeMultiplier(float sizeMultiplier);

  Bitmap get(int width, int height, Bitmap.Config config);

  Bitmap getDirty(int width, int height, Bitmap.Config config);

  void clearMemory();

  void trimMemory(int level);
}

Bitmap缓存池的接口,作用是复用Bitmap对象内存,当一个Bitmap不再被使用时,Glide会把Bitmap占用的内存放到缓存池中,当有相同参数的Bitmap需要创建时,优先从缓存池中请求内存,避免频繁分配内存。与Handler的Message对象复用思路一致。默认实现是LruBitmapPool,采用LRU原则控制缓存大小。

put

Glide中放入缓存池的时机,主要在两个地方:
1、bitmap 被回收(recycle)
2、bitmap作为临时变量,暂时为生成其他bitmap存储数据

被回收容易理解,put调用通常位于recycle方法中:

public class BitmapDrawableResource{
  
  @Override
  public void recycle() {
    bitmapPool.put(drawable.getBitmap());
  }
  
}
public class BitmapResource{
  
  @Override
  public void recycle() {
    bitmapPool.put(drawable.getBitmap());
  }
  
}
final class BitmapPreFillRunner implements Runnable {
	
  boolean allocate() {
     bitmapPool.put(bitmap);
  }

}

作为中间变量存储数据是指,当Glide获取了图片的原始数据,但是图片需要处理后,才能被使用,所以put调用常常位于数据解析后,但是被应用前的位置:

public final class Downsampler {
	//从inputStream解析数据
	private Bitmap decodeFromWrappedStreams(...){	
		bitmapPool.put(downsampled);
	}

	private static Bitmap decodeStream(...){
		bitmapPool.put(options.inBitmap);
	}

}
public class StreamBitmapDecoder{
	//从inputStream解析数据
	public void onDecodeComplete(...){
	  bitmapPool.put(downsampled);
	}

}
public final class TransformationUtils {
	//对图片进行变换
	public static Bitmap circleCrop(...){
		pool.put(toTransform);
	}
	//对图片进行变换
	public static Bitmap roundedCorners(...){
		pool.put(toTransform);
	}
	
}

get

get方法应用的地方集中在图片变换的步骤中:从缓存池获取bitmap内存,把最后需要使用的图片数据,放到bitmap中。

public final class TransformationUtils {

   private static Bitmap drawToBitmap(){
	      Bitmap result = bitmapPool.get(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
   }
	

	public static Bitmap circleCrop(...){
    	Bitmap result = pool.get(width, height, getNonNullConfig(inBitmap));
	}

	public static Bitmap centerCrop(...){
    	Bitmap result = pool.get(width, height, getNonNullConfig(inBitmap));
	}

	public static Bitmap rotateImageExif(...){
    	Bitmap result = pool.get(width, height, getNonNullConfig(inBitmap));
	}

	public static Bitmap fitCenter(...){
    	Bitmap result = pool.get(width, height, getNonNullConfig(inBitmap));
	}

	public static Bitmap roundedCorners(...){
		pool.put(toTransform);
	}
	
}

ArrayPool

理解了BitmapPool,其实ArrayPool也差不多。Glide需要处理很多图片的数据,不可避免的要从InputStream中读取数据,这时候就要用到byte数组(byte[]),ArrayPool作用就是缓存byte数组,避免频繁创建对象。

最后

理解源码不是最终目的,纸上得来终觉浅,绝知此事要躬行,学习优秀的代码,最重要的是掌握其中的思想,并应用到自己的项目中。
Glide的开发者们在一开始,一定没有想到内存方面的优化,而是通过性能分析,定位到这里,并提出这样一个解决方案。
因此,必须掌握如何分析app内存:
Android性能优化:使用Profiler进行内存优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值