Android自制圖片的三級快取(程式碼+講解)
阿新 • • 發佈:2019-02-09
Android的圖片三級快取機制
首先
圖片的三計劃快取的概念
泛指的是 -記憶體快取 -本地快取 -網路快取
記憶體快取的概念:
應用程式在執行時 WindowMeanger會分配給 應用 相應的執行時記憶體
執行是記憶體的大小根據android版本有關係
本地快取的概念
本地快取是儲存在硬體上的資料
網路快取的概念
圖片儲存在網路上,需要下載
小結
這三種快取的概念以上以及陳述了,既然我們要做一個服務於圖片的快取,那麼
我們就要應用起來這三種快取到 我們的這個 demo裡面
要應用它 首先 我們做一下專案規劃 這個快取 每一個快取都要是個單獨的類
保持封裝性 然後呼叫的時候要簡單 一行程式碼就呼叫
那麼我們 還要做一個 proxy
好 下面開始
記憶體設計程式碼
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
/**
* LruCache工具類
* @author 浩
*
*/
public class MemoryCacheUtils {
private LruCache<String, Bitmap> lruCache;//集合
public MemoryCacheUtils() {
int maxSize = (int) Runtime.getRuntime().maxMemory();
lruCache = new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
// TODO Auto-generated method stub
return value.getRowBytes() * value.getHeight();
}
};
}
/**
* 根據url從記憶體中得到快取圖片
* @param url
* @return
*/
public Bitmap getBitmapFromUril(String url) {
// TODO Auto-generated method stub
return lruCache.get(url);
}
/**
* 根據url,和bitmp在記憶體中儲存一份bitmap
* @param url
* @param bitmap
*/
public void putBitmap2Memory(String url, Bitmap bitmap) {
//每個應用佔多少記憶體:16MB
lruCache.put(url, bitmap);
}
}
本地快取設計
mport android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.widget.ImageView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class LocalCacheUtils {
/**
* 本地快取工具類
*
* @author 王浩
*
*/
private static final String ATGUIT_DIR = "/mnt/sdcard/beijingnews/";
/**
* 根據Bitmap儲存圖片到本地
*
* @param url
* @param bitmap
*/
public void putBitmap2Local(String url, Bitmap bitmap) {
// TODO Auto-generated method stub
try {
// String name = MD5Encoder.encode(url);
// /mnt/sdcard/beijingnews/lskkskklllkk(md5加密)
File file = new File(ATGUIT_DIR, url);
// mnt/sdcard/beijingnews/建立
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
// 圖片就儲存到sdcard了
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, stream);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根據uri取對應的圖片
*
* @param url
* @return
*/
public Bitmap getBitmapFromUrl(String url, ImageView imageView, int tag) {
try {
File file = new File(ATGUIT_DIR, url);
if (file.isFile()) {
Bitmap bitmap = null ;
FileInputStream fis = new FileInputStream(file);
fis.close();
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
網路快取設計
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 網路快取圖片的工具類
*
* @author 王浩
*/
public class NetCatchUtils {
/**
* 網路請求圖片成功
*/
public static final int SUCESS = 0;
/**
* 網路請求圖片失敗
*/
public static final int FAIL = 1;
private Handler handler;
/**
* 本地快取工具類
*/
private LocalCacheUtils localCacheUtils;
/**
* 記憶體快取工具
*/
private MemoryCacheUtils memoryCacheUtils;
public NetCatchUtils(Handler handler, LocalCacheUtils localCacheUtils,
MemoryCacheUtils memoryCacheUtils) {
// TODO Auto-generated constructor stub
this.handler = handler;
this.localCacheUtils = localCacheUtils;
this.memoryCacheUtils = memoryCacheUtils;
}
/**
* 根據圖片路徑,請求網路圖片
*
* @param url
* @param position
* @return
*/
public Bitmap getBitmapFromUrl(String url, int position, int tag,
Activity ac, ImageView tv_image) {
new Thread(new MyRunnable(url, position, tag, ac, tv_image)).start();
return null;
}
class MyRunnable implements Runnable {
private String url;
private int position;
private int tag;
private Activity ac;
private ImageView tv_image;
public MyRunnable(String url, int position, int tag, Activity ac,
ImageView tv_image) {
this.url = url;
this.position = position;
this.tag = tag;
this.ac = ac;
this.tv_image = tv_image;
}
/**
* 處理大圖片載入問題
*/
@Override
public void run() {
HttpURLConnection con = null;
try {
con = (HttpURLConnection) new
URL(url).openConnection();
int code = con.getResponseCode();
if (200 == code) {
InputStream is = con.getInputStream();
Options opts = new Options();
// 根據計算出的比例進行縮放
int scale = ImageUtils.getScare(url, ac);
opts.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeStream(is, null, opts);
// 將bm發生給主執行緒用於顯示圖片,更新UI
Message msg = Message.obtain();
msg.obj = bm;
msg.arg1 = tag;
msg.arg2 = position;
tv_image.post(new Action(bm, tv_image));
// if(handler!=null) {
// tv_image.post(new Action(bm, tv_image));
// //handler.sendMessage(msg);
// } else {
// Utils.log2("tv_image:" + bm + "————tv_image:" + tv_image);
// //tv_image.setImageBitmap(bm);
//
//
// }
// 儲存一份在記憶體
memoryCacheUtils.putBitmap2Memory(url, bm);
// 儲存一份在本地(Sdcard)
localCacheUtils.putBitmap2Local(url, bm);
}
} catch (Exception e) {
// e.printStackTrace();
}
}
}
/**
* 在主執行緒更新UI
*/
class Action implements Runnable{
private Bitmap bit ;
private ImageView img ;
public Action(Bitmap bit,ImageView img) {
this.bit = bit;
this.img = img;
}
@Override
public void run() {
img.setImageBitmap(bit);
}
}
}
代理者設計
/**
* 三級快取工具類
*
* @author wanghao
*
*/
public class ImageCacheProxy {
public static final int LARGE_PHOTO = -11 ;
/**
* 一級本地快取
*/
LocalCacheUtils localCacheUtils;
/**
* 二級記憶體快取
*/
private MemoryCacheUtils memoryCacheUtils;
/**
* 三級網路獲取圖片
*/
private NetCatchUtils netUtils ;
/**
* 初始化三級快取
* @param handler
*/
public ImageCacheProxy() {
localCacheUtils = new LocalCacheUtils();
memoryCacheUtils = new MemoryCacheUtils();
netUtils = new NetCatchUtils(null, localCacheUtils, memoryCacheUtils);
}
/**
* @param tv_image 要把bit替換成image的image
* @param url 請求圖片的地址
* @param position 給圖片做的tag 方便 handler ,裡面 去取
* @param tag arg1的標記
*/
public void imageLoader(ImageView tv_image, String url, int position, int tag ,Activity ac) {
Bitmap bit;
bit = localCacheUtils.getBitmapFromUrl(url,tv_image,tag);
if (bit != null) {
tv_image.setImageBitmap(bit);
return;
}
bit = memoryCacheUtils.getBitmapFromUril(url);
if (bit != null) {
tv_image.setImageBitmap(bit);
return;
}
netUtils.getBitmapFromUrl(url, position, tag ,ac,tv_image);
}
}
這就OK了 呼叫 只需要一行程式碼loader下 就行了
附上我寫的 demo project 地址
本篇部落格結束
如果覺得對你有幫助
粉我把
關注更多我的blog.
技術交流群:
部落格圈 493554215
這是一個熱愛分享技術,擁有熱烈學習氛圍的群 ,
博主身為群內的一員感到驕傲
推薦還在路上的夥伴們