一、內(nèi)存緩存(一級)
public class MemoryCacheUtils {
存放圖片的集合
private HashMap<String,SoftReference<Bitmap>> mHashMap =new HashMap<>();
設(shè)置一級緩存(原理)
public void setMemoryCache(String url, Bitmap bitmap){
SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
mHashMap.put(url,softReference);
mLruCache.put(url,bitmap);?
}
獲取一級緩存(原理)
public Bitmap getMemoryCache(String url){
SoftReference<Bitmap> softReference =mHashMap.get(url);
if(softReference != null){
Bitmap bitmap =softReference.get();
return bitmap;
}
return null;
return mLruCache.get(url);
}
}
優(yōu)化:使用LruCache算法(least recentlly used cache)熄阻,告別軟引用和弱引用,內(nèi)部核心是通過算法實現(xiàn)緩存的大小控制佳窑,封裝HashMap,使用更加方便簡單。使用LruCache代替上述的HashMap漾肮。
private LruCache<String,Bitmap> mLruCache;
構(gòu)造方法初始化LruCache
public MemoryCacheUtils(){
//獲取虛擬機分配的最大內(nèi)存,默認16M
?long maxMemory = Runtime.getRuntime().maxMemory();
//參數(shù)是內(nèi)存緩存上限
mLruCache =new LruCache((int) (maxMemory/8)){
@Override
?protected int sizeOf(String key, Bitmap value) {
//獲取單個對象占用字節(jié)數(shù)大小
//int byteCount = value.getByteCount();
//兼容低版本,一行字節(jié)數(shù)*總行數(shù)
??int byteCount =value.getRowBytes()*value.getHeight();
//返回單個對象占用內(nèi)存大小
?return byteCount;
}
};
二谤狡、本地緩存(二級)
public class LocalCacheUtils {
需要存放本地緩存的目錄路徑
String path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/自定義/";
設(shè)置本地緩存
public void setLocalCache(String url, Bitmap bitmap) {
File dir =new File(path);
if (!dir.exists() || !dir.isDirectory()) { ?// 不存在 或者 不是目錄
//創(chuàng)建此抽象路徑名指定的目錄?//dir.mkdir();
//創(chuàng)建此抽象路徑名指定的目錄灸眼,包括所有必需但不存在的父目錄。
?dir.mkdirs();
}
//url需要經(jīng)過處理
??File file =new File(dir, url);
//將圖片壓縮到本地
?try {
//參數(shù)1是圖片格式墓懂,參數(shù)2是壓縮比(0-100)焰宣,100代表不壓縮,參數(shù)3是文件輸出流 ? bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
}catch (FileNotFoundException e) {
e.printStackTrace();
}
}
獲取本地緩存
public Bitmap getLocalCache(String url) {
//url需要經(jīng)過處理
??try {
File cacheFile =new File(path, url);
if (cacheFile.exists()) { ?//緩存存在
?Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile));
return bitmap;
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
三、網(wǎng)絡(luò)緩存(三級)
public class NetCacheUtils {
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(MemoryCacheUtils memoryCacheUtils,LocalCacheUtils localCacheUtils) {
mMemoryCacheUtils=memoryCacheUtils;
mLocalCacheUtils=localCacheUtils;
}
獲取網(wǎng)絡(luò)圖片
public void getBitmapFromNet(ImageView imageView,String url){
?new BitmapTask().execute(imageView,url);
}
異步加載網(wǎng)絡(luò)圖片的內(nèi)部類
class BitmapTaskextends AsyncTask<Object,Void,Bitmap>{
private ImageView mImageView;
@Override
protected void onPreExecute() { //預(yù)操作
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Object... params) {//耗時操作
//根據(jù)異步加載時傳入的參數(shù)順序來獲取參數(shù)
mImageView = (ImageView) params[0];
String url = (String) params[1];
//防止網(wǎng)絡(luò)慢時捕仔,控件與加載的圖片顯示不符(ListView)
mImageView.setTag(url);
//網(wǎng)絡(luò)訪問
download(url);
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) { ?//后續(xù)操作
doInBackground返回的值作為參數(shù)傳入本方法
?if(bitmap!=null){
mImageView.setImageBitmap(bitmap);
String url= (String)mImageView.getTag();
寫入本地緩存
mLocalCacheUtils.setLocalCache(url,bitmap);
寫入內(nèi)存緩存
?mMemoryCacheUtils.setMemoryCache(url,bitmap);
}
}
}
}
四匕积、三級緩存綜合使用
public class BitmapUtils {
private NetCacheUtils mNetCacheUtils;
private LocalCacheUtils mLocalCacheUtils;
private MemoryCacheUtils mMemoryCacheUtils;
public BitmapUtils(){
mMemoryCacheUtils =new MemoryCacheUtils();
mLocalCacheUtils =new LocalCacheUtils();
mNetCacheUtils =new NetCacheUtils(mMemoryCacheUtils,mLocalCacheUtils);
}
通過優(yōu)先級加載圖片
public void displayBitmap(ImageView imageView,String url){
內(nèi)存緩存
Bitmap bitmap=mMemoryCacheUtils.getMemoryCache(url);
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
return;
}
本地緩存
Bitmap bitmap1=mLocalCacheUtils.getLocalCache(url);
if(bitmap1!=null){
imageView.setImageBitmap(bitmap1);
mMemoryCacheUtils.setMemoryCache(url,bitmap1);
return;
}
網(wǎng)絡(luò)緩存
mNetCacheUtils.getBitmapFromNet(imageView,url);
}
}
五、Android之四大引用
簡介:Java虛擬機存在棧和堆榜跌,棧存放變量闪唆,堆存放類,它們之間存在一種引用關(guān)系
1钓葫、強引用:默認都是強引用悄蕾,不會回收
2、軟引用:當內(nèi)存不足時础浮,垃圾回收器會考慮回收
創(chuàng)建:SoftReference<Bitmap>?softReference=new SoftReference<Bitmap>(bitmap);
從軟引用中取出:Bitmap bitmap =softReference.get();
3帆调、弱引用:當內(nèi)存不足時,垃圾回收器更會考慮回收豆同,
4番刊、虛引用:當內(nèi)存不足時,垃圾回收器最先考慮回收
5影锈、垃圾:一些沒有被引用的對象稱之為垃圾