国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android圖片三級(jí)緩存開發(fā)

2019-10-22 18:16:31
字體:
供稿:網(wǎng)友

因?yàn)槟壳肮こ虩o法使用第三方,只能搞一個(gè)三級(jí)緩存了三級(jí)緩存分為內(nèi)存緩存,本地緩存,網(wǎng)絡(luò)緩存;緩存的步驟依次是網(wǎng)絡(luò),內(nèi)存,本地,然后取的順序?yàn)閮?nèi)存,本地,網(wǎng)絡(luò)。在加載圖片時(shí)引用時(shí)盡量采用弱引用避免出現(xiàn)圖片過多產(chǎn)生OOM.。

1、內(nèi)存緩存,android為我們提供LruCache=其中維護(hù)著一個(gè)LinkedHashMap。LruCache可以用來存儲(chǔ)各種類型的數(shù)據(jù),我們?cè)O(shè)置它的大小,一般是系統(tǒng)最大存儲(chǔ)空間的1/8.

public class MemoryCacheUtil { private LruCache<String, Bitmap> lruCache; public MemoryCacheUtil(){  int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);  // 一般獲取當(dāng)前應(yīng)用的最大內(nèi)存的1/8作為L(zhǎng)ruCache的容量  lruCache = new LruCache<String, Bitmap>(maxSize){   // 設(shè)置當(dāng)前添加的圖片的大小   @Override   protected int sizeOf(String key, Bitmap value) {    return value.getRowBytes()*value.getHeight();   }  }; } // 從內(nèi)存緩存取圖片 public Bitmap getBitmap(String url){  return lruCache.get(url); } // 在內(nèi)存緩存存圖片 public void putBitmap(String url,Bitmap bitmap){  lruCache.put(url, bitmap); }}

2、本地緩存根據(jù)url,獲取本地文件,把url進(jìn)行md5加密,作為文件名,保證文件的正確性.

MD5加密工具類

public class MD5Encoder { public static String encode(String string) throws Exception {  byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));  StringBuilder hex = new StringBuilder(hash.length * 2);  for (byte b : hash) {   if ((b & 0xFF) < 0x10) {    hex.append("0");   }   hex.append(Integer.toHexString(b & 0xFF));  }  return hex.toString(); }}

本地緩存

public class LocalCacheUtil { private String CACHE_URl; private MemoryCacheUtil memoryCacheUtil; public LocalCacheUtil(MemoryCacheUtil memoryCacheUtil){  // 初始化本地存儲(chǔ)的路徑  CACHE_URl = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/test";  this.memoryCacheUtil = memoryCacheUtil; } // 從本地sdcard取圖片 public Bitmap getBitmap(String url){  // 根據(jù)url,獲取本地文件,把url進(jìn)行md5加密,作為文件名  try {   String fileName = MD5Encoder.encode(url);   File file = new File(CACHE_URl, fileName);   if(file.exists()){// 判斷當(dāng)前文件是否存在    // 把當(dāng)前文件轉(zhuǎn)換成Bitmap對(duì)象    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());    // 需往內(nèi)存中存一份    memoryCacheUtil.putBitmap(url, bitmap);    return bitmap;   }  } catch (Exception e) {   e.printStackTrace();  }  return null; } // 往本地存圖片的方法 public void saveBitmap(String url,Bitmap bitmap){  try {   String fileName = MD5Encoder.encode(url);   File file = new File(CACHE_URl, fileName);   // 判斷是否需要?jiǎng)?chuàng)建父目錄   File parentFile = file.getParentFile();   if(!parentFile.exists()){    parentFile.mkdirs();   }   // 把Bitmap對(duì)象保存到文件中 質(zhì)量越高壓縮速度越慢   OutputStream stream = new FileOutputStream(file);   bitmap.compress(CompressFormat.PNG, 100, stream);//第一個(gè)參數(shù)可以設(shè)置圖片格式,第二個(gè)圖片壓縮質(zhì)量,第三個(gè)為圖片輸出流  } catch (Exception e) {   e.printStackTrace();  } }}

3、網(wǎng)絡(luò)緩存使用異步加載AsyncTask,使用其有二種原因:

1.doInBackground運(yùn)行在子線程,做網(wǎng)絡(luò)請(qǐng)求耗時(shí)操作,避免主線程堵塞;

2.onPreExecute和onPostExecute便于更新UI提高用戶體驗(yàn)。

public class NetCacheUtil { private MemoryCacheUtil memoryCacheUtil; private LocalCacheUtil localCacheUtil; private ListView lv_image_list; public NetCacheUtil(MemoryCacheUtil memoryCacheUtil,LocalCacheUtil localCacheUtil){  this.memoryCacheUtil = memoryCacheUtil;  this.localCacheUtil = localCacheUtil; } public void display(ImageView imageView ,String url, ListView lv_image_list){   this.lv_image_list = lv_image_list;  new MyAsyncTask(imageView).execute(new Object[]{url,imageView}); } class MyAsyncTask extends AsyncTask<Object, Void, Bitmap>{  private ImageView imageView;  private int position;  public MyAsyncTask(ImageView imageView2) {   position = (Integer) imageView2.getTag();  }  // 運(yùn)行在主線程,做準(zhǔn)備操作,在doInBackground之前,可以放置加載條提高用戶體驗(yàn)  @Override  protected void onPreExecute() {   super.onPreExecute();  }  // 運(yùn)行在子線程,做耗時(shí)操作  @Override  protected Bitmap doInBackground(Object... params) {   // 獲取url,下載圖片   String url = (String) params[0];   // 獲取ImageView   imageView = (ImageView) params[1];   try {    // 下載圖片    HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();    conn.connect();// 連接網(wǎng)絡(luò)    // 獲取響應(yīng)碼    int resCode = conn.getResponseCode();    if(resCode==200){// 訪問成功     // 把服務(wù)器返回的輸入流轉(zhuǎn)換成Bitmap對(duì)象     Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream());     // 保存到本地和內(nèi)存     memoryCacheUtil.putBitmap(url, bitmap);     localCacheUtil.saveBitmap(url, bitmap);     return bitmap;    }   } catch (Exception e) {    e.printStackTrace();   }   return null;  }  // 運(yùn)行在主線程,更新界面,在doInBackground之后  @Override  protected void onPostExecute(Bitmap result) {   // 判斷線程開始時(shí),那個(gè)位置是否還在Listview中   ImageView view = (ImageView) lv_image_list.findViewWithTag(position);   if(view!=null){    view.setImageBitmap(result);   }   super.onPostExecute(result);  } }}

4、封裝三級(jí)緩存形成ImageUtil,因內(nèi)存緩存中取速度較快,所以先從內(nèi)存緩存中取,取不到->本地緩存中取,取不到->網(wǎng)絡(luò)緩存中取。

public class ImageUtils { private MemoryCacheUtil memoryCacheUtil; private LocalCacheUtil localCacheUtil; private NetCacheUtil netCacheUtil; public ImageUtils(){  memoryCacheUtil = new MemoryCacheUtil();  localCacheUtil = new LocalCacheUtil(memoryCacheUtil);  netCacheUtil = new NetCacheUtil(memoryCacheUtil,localCacheUtil); }  public void display(ImageView imageView, String url, ListView lv_photo_list) {  Bitmap bitmap = null;  /**   * 因內(nèi)存緩存中取速度較快   * 內(nèi)存緩存中取,取不到->本地緩存中取,取不到->網(wǎng)絡(luò)緩存中取   */  bitmap = memoryCacheUtil.getBitmap(url);//從內(nèi)存緩存取圖片  if(bitmap!=null){   imageView.setImageBitmap(bitmap);   return;  }  bitmap = localCacheUtil.getBitmap(url);//從本地緩存取圖片  if(bitmap!=null){   imageView.setImageBitmap(bitmap);   return;  }  // 開啟線程訪問網(wǎng)絡(luò),下載圖片,并且展示  netCacheUtil.display(imageView, url,lv_photo_list); }}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 株洲市| 克东县| 龙岩市| 准格尔旗| 台北市| 鹿邑县| 威宁| 巴彦淖尔市| 隆安县| 凉城县| 色达县| 交城县| 南部县| 临夏县| 遂溪县| 革吉县| 荥经县| 万载县| 若羌县| 柯坪县| 东兴市| 鞍山市| 台中市| 法库县| 讷河市| 兰州市| 开阳县| 宿迁市| 田林县| 灌阳县| 民县| 且末县| 巴里| 余庆县| 惠来县| 罗源县| 肃宁县| 金华市| 通化市| 扎赉特旗| 诸城市|