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

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

詳解Android 圖片的三級緩存及圖片壓縮

2019-12-12 04:24:04
字體:
供稿:網(wǎng)友

為什么需要圖片緩存

Android默認給每個應用只分配16M的內(nèi)存,所以如果加載過多的圖片,為了防止內(nèi)存溢出,應該將圖片緩存起來。圖片的三級緩存分別是:

  • 內(nèi)存緩存
  • 本地緩存
  • 網(wǎng)絡緩存

其中,內(nèi)存緩存應優(yōu)先加載,它速度最快;本地緩存次優(yōu)先加載,它速度也快;網(wǎng)絡緩存不應該優(yōu)先加載,它走網(wǎng)絡,速度慢且耗流量。

三級緩存的具體實現(xiàn)

網(wǎng)絡緩存

  • 根據(jù)圖片的url去加載圖片
  • 在本地和內(nèi)存中緩存

  

 public class NetCacheUtils {    private LocalCacheUtils mLocalCacheUtils;    private MemoryCacheUtils mMemoryCacheUtils;    public NetCacheUtils(LocalCacheUtils localCacheUtils,        MemoryCacheUtils memoryCacheUtils) {      mLocalCacheUtils = localCacheUtils;      mMemoryCacheUtils = memoryCacheUtils;    }    /**     * 從網(wǎng)絡下載圖片     *      * @param ivPic     * @param url     */    public void getBitmapFromNet(ImageView ivPic, String url) {      new BitmapTask().execute(ivPic, url);// 啟動AsyncTask,                          // 參數(shù)會在doInbackground中獲取    }    /**     * Handler和線程池的封裝     *      * 第一個泛型: 參數(shù)類型 第二個泛型: 更新進度的泛型, 第三個泛型是onPostExecute的返回結(jié)果     *      *      */    class BitmapTask extends AsyncTask<Object, Void, Bitmap> {      private ImageView ivPic;      private String url;      /**       * 后臺耗時方法在此執(zhí)行, 子線程       */      @Override      protected Bitmap doInBackground(Object... params) {        ivPic = (ImageView) params[0];        url = (String) params[1];        ivPic.setTag(url);// 將url和imageview綁定        return downloadBitmap(url);      }      /**       * 更新進度, 主線程       */      @Override      protected void onProgressUpdate(Void... values) {        super.onProgressUpdate(values);      }      /**       * 耗時方法結(jié)束后,執(zhí)行該方法, 主線程       */      @Override      protected void onPostExecute(Bitmap result) {        if (result != null) {          String bindUrl = (String) ivPic.getTag();          if (url.equals(bindUrl)) {// 確保圖片設定給了正確的imageview            ivPic.setImageBitmap(result);            mLocalCacheUtils.setBitmapToLocal(url, result);// 將圖片保存在本地            mMemoryCacheUtils.setBitmapToMemory(url, result);// 將圖片保存在內(nèi)存            System.out.println("從網(wǎng)絡緩存讀取圖片啦...");          }        }      }    }    /**     * 下載圖片     *      * @param url     * @return     */    private Bitmap downloadBitmap(String url) {      HttpURLConnection conn = null;      try {        conn = (HttpURLConnection) new URL(url).openConnection();        conn.setConnectTimeout(5000);        conn.setReadTimeout(5000);        conn.setRequestMethod("GET");        conn.connect();        int responseCode = conn.getResponseCode();        if (responseCode == 200) {          InputStream inputStream = conn.getInputStream();          //圖片壓縮處理          BitmapFactory.Options option = new BitmapFactory.Options();          option.inSampleSize = 2;//寬高都壓縮為原來的二分之一, 此參數(shù)需要根據(jù)圖片要展示的大小來確定          option.inPreferredConfig = Bitmap.Config.RGB_565;//設置圖片格式          Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);          return bitmap;        }      } catch (Exception e) {        e.printStackTrace();      } finally {        conn.disconnect();      }      return null;    }  }

本地緩存

兩個方法:設置本地緩存,獲取本地緩存

  public class LocalCacheUtils {    public static final String CACHE_PATH = Environment        .getExternalStorageDirectory().getAbsolutePath() + "/local_cache";    /**     * 從本地sdcard讀圖片     */    public Bitmap getBitmapFromLocal(String url) {      try {        String fileName = MD5Encoder.encode(url);        File file = new File(CACHE_PATH, fileName);        if (file.exists()) {          Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(              file));          return bitmap;        }      } catch (Exception e) {        e.printStackTrace();      }      return null;    }    /**     * 向sdcard寫圖片     *      * @param url     * @param bitmap     */    public void setBitmapToLocal(String url, Bitmap bitmap) {      try {        String fileName = MD5Encoder.encode(url);        File file = new File(CACHE_PATH, fileName);        File parentFile = file.getParentFile();        if (!parentFile.exists()) {// 如果文件夾不存在, 創(chuàng)建文件夾          parentFile.mkdirs();        }        // 將圖片保存在本地        bitmap.compress(CompressFormat.JPEG, 100,            new FileOutputStream(file));      } catch (Exception e) {        e.printStackTrace();      }    }  }

內(nèi)存緩存

兩個方法:設置內(nèi)存緩存,獲取內(nèi)存緩存

問題:

如果使用HashMap存儲圖片時,當圖片越來越多時,會導致內(nèi)存溢出,因為它是強引用,java的垃圾回收器不會回收。

如若改成軟引用SoftReference(內(nèi)存不夠時,垃圾回收器會考慮回收),仍有一個問題:在android2.3+, 系統(tǒng)會優(yōu)先將SoftReference的對象提前回收掉, 即使內(nèi)存夠用。

解決辦法:可以用LruCache來解決上述內(nèi)存不回收或提前回收的問題。least recentlly use 最少最近使用算法 它會將內(nèi)存控制在一定的大小內(nèi), 超出最大值時會自動回收, 這個最大值開發(fā)者自己定
 

    public class MemoryCacheUtils {      // private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new      // HashMap<String, SoftReference<Bitmap>>();      private LruCache<String, Bitmap> mMemoryCache;      public MemoryCacheUtils() {        long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模擬器默認是16M        mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {          @Override          protected int sizeOf(String key, Bitmap value) {            int byteCount = value.getRowBytes() * value.getHeight();// 獲取圖片占用內(nèi)存大小            return byteCount;          }        };      }      /**       * 從內(nèi)存讀       *        * @param url       */      public Bitmap getBitmapFromMemory(String url) {        // SoftReference<Bitmap> softReference = mMemoryCache.get(url);        // if (softReference != null) {        // Bitmap bitmap = softReference.get();        // return bitmap;        // }        return mMemoryCache.get(url);      }      /**       * 寫內(nèi)存       *        * @param url       * @param bitmap       */      public void setBitmapToMemory(String url, Bitmap bitmap) {        // SoftReference<Bitmap> softReference = new        // SoftReference<Bitmap>(bitmap);        // mMemoryCache.put(url, softReference);        mMemoryCache.put(url, bitmap);      }    }

圖片壓縮

  //圖片壓縮處理(在從網(wǎng)絡獲取圖片的時候就進行壓縮)  BitmapFactory.Options option = new BitmapFactory.Options();  option.inSampleSize = 2;//寬高都壓縮為原來的二分之一, 此參數(shù)需要根據(jù)圖片要展示的大小來確定  option.inPreferredConfig = Bitmap.Config.RGB_565;//設置圖片格式  Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 土默特右旗| 麻栗坡县| 冷水江市| 保德县| 沙洋县| 临沂市| 柳林县| 莲花县| 纳雍县| 南木林县| 房产| 双鸭山市| 余干县| 潜江市| 连平县| 锡林浩特市| 阜平县| 伊宁县| 双牌县| 迁安市| 南溪县| 青阳县| 博客| 濉溪县| 云龙县| 长治市| 陆河县| 子长县| 彭泽县| 广灵县| 红桥区| 新宾| 壶关县| 宝兴县| 雷州市| 台中市| 绍兴市| 西城区| 常宁市| 楚雄市| 忻城县|