亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2018年01月24日 10:42:05   作者:WhatYouSeeMe  
這篇文章主要為大家詳細介紹了Android圖片三級緩存開發(fā)的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

因為目前工程無法使用第三方,只能搞一個三級緩存了三級緩存分為內(nèi)存緩存,本地緩存,網(wǎng)絡緩存;緩存的步驟依次是網(wǎng)絡,內(nèi)存,本地,然后取的順序為內(nèi)存,本地,網(wǎng)絡。在加載圖片時引用時盡量采用弱引用避免出現(xiàn)圖片過多產(chǎn)生OOM.。

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

public class MemoryCacheUtil {

 private LruCache<String, Bitmap> lruCache;

 public MemoryCacheUtil(){
  int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);

  // 一般獲取當前應用的最大內(nèi)存的1/8作為LruCache的容量
  lruCache = new LruCache<String, Bitmap>(maxSize){
   // 設置當前添加的圖片的大小
   @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進行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){
  // 初始化本地存儲的路徑
  CACHE_URl = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/test";
  this.memoryCacheUtil = memoryCacheUtil;
 }

 // 從本地sdcard取圖片
 public Bitmap getBitmap(String url){
  // 根據(jù)url,獲取本地文件,把url進行md5加密,作為文件名
  try {
   String fileName = MD5Encoder.encode(url);
   File file = new File(CACHE_URl, fileName);
   if(file.exists()){// 判斷當前文件是否存在
    // 把當前文件轉換成Bitmap對象
    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);
   // 判斷是否需要創(chuàng)建父目錄
   File parentFile = file.getParentFile();
   if(!parentFile.exists()){
    parentFile.mkdirs();
   }
   // 把Bitmap對象保存到文件中 質(zhì)量越高壓縮速度越慢
   OutputStream stream = new FileOutputStream(file);
   bitmap.compress(CompressFormat.PNG, 100, stream);//第一個參數(shù)可以設置圖片格式,第二個圖片壓縮質(zhì)量,第三個為圖片輸出流
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

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

1.doInBackground運行在子線程,做網(wǎng)絡請求耗時操作,避免主線程堵塞;

2.onPreExecute和onPostExecute便于更新UI提高用戶體驗。

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();
  }

  // 運行在主線程,做準備操作,在doInBackground之前,可以放置加載條提高用戶體驗
  @Override
  protected void onPreExecute() {
   super.onPreExecute();
  }

  // 運行在子線程,做耗時操作
  @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)絡
    // 獲取響應碼
    int resCode = conn.getResponseCode();
    if(resCode==200){// 訪問成功
     // 把服務器返回的輸入流轉換成Bitmap對象
     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;
  }
  // 運行在主線程,更新界面,在doInBackground之后
  @Override
  protected void onPostExecute(Bitmap result) {
   // 判斷線程開始時,那個位置是否還在Listview中
   ImageView view = (ImageView) lv_image_list.findViewWithTag(position);
   if(view!=null){
    view.setImageBitmap(result);
   }
   super.onPostExecute(result);
  }
 }
}

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

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)絡緩存中取
   */
  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)絡,下載圖片,并且展示
  netCacheUtil.display(imageView, url,lv_photo_list);
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論