乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      圖片緩存之內(nèi)存緩存技術(shù)LruCache,軟引用

       winkinglib 2015-05-05
      每當(dāng)碰到一些大圖片的時(shí)候,我們?nèi)绻粚?duì)圖片進(jìn)行處理就會(huì)報(bào)OOM異常,
      這個(gè)
      問題曾經(jīng)讓我覺得很煩惱,后來終于得到了解決,
      那么現(xiàn)在就讓我和大家一起分享一下吧。
      這篇博文要講的圖片緩存機(jī)制,我接觸到的有兩鐘,一種是軟引用,另一種是內(nèi)存緩存技術(shù)。
      先來看下兩者的使用方式,再來作比較。
      除了加載圖片時(shí)要用到緩存處理,還有一個(gè)比較重要的步驟要做,就是要先壓縮圖片。

      1、壓縮圖片
      至于要壓縮到什么狀態(tài)就要看自己當(dāng)時(shí)的處境了,壓縮圖片的時(shí)候既要達(dá)到一個(gè)小的值,又不能讓其模糊
      ,更不能拉伸圖片。

      1. /**
      2.          * 加載內(nèi)存卡圖片
      3.          */
      4.         BitmapFactory.Options options = new BitmapFactory.Options();
      5.         options.inJustDecodeBounds = true; // 設(shè)置了此屬性一定要記得將值設(shè)置為false
      6.         Bitmap bitmap = null;
      7.         bitmap = BitmapFactory.decodeFile(url, options);
      8.         int be = (int) ((options.outHeight > options.outWidth ? options.outHeight / 150
      9.                 : options.outWidth / 200));
      10.         if (be <= 0) // 判斷200是否超過原始圖片高度
      11.             be = 1; // 如果超過,則不進(jìn)行縮放
      12.         options.inSampleSize = be;
      13.         options.inPreferredConfig = Bitmap.Config.ARGB_4444;
      14.         options.inPurgeable = true;
      15.         options.inInputShareable = true;
      16.         options.inJustDecodeBounds = false;
      17.         try {
      18.             bitmap = BitmapFactory.decodeFile(url, options);
      19.         } catch (OutOfMemoryError e) {
      20.             System.gc();
      21.             Log.e(TAG, "OutOfMemoryError");
      22.         }


      2、軟引用:
      只要有足夠的內(nèi)存,就一直保持對(duì)象,直到發(fā)現(xiàn)內(nèi)存吃緊且沒有
      Strong Ref時(shí)才回收對(duì)象。
      我們可以這樣定義:map里面的鍵是用來放圖片地址的,既可以是網(wǎng)絡(luò)上的圖片地址,也可以SDcard上的圖片地址,
      map里面的值里面放的是持有軟引用的Bitmap,當(dāng)然如果你要放Drawable,那也是可以的。

      1. private Map<String, SoftReference<Bitmap>> imageMap 
      2.                                            = new HashMap<String, SoftReference<Bitmap>>();
      接下來就讓我再介紹一下如何具體加載圖片:
      步驟:(1)先通過URL查看緩存中是否有圖片,如果有,則直接去緩存中取得。
                 如果沒有,就開線程重新去網(wǎng)上下載。
            (2)下載完了之后,就把圖片放在緩存里面,方便下次可以直接從緩存中取得。
      1. public Bitmap loadBitmap(final String imageUrl,final ImageCallBack imageCallBack) {
      2.         SoftReference<Bitmap> reference = imageMap.get(imageUrl);
      3.         if(reference != null) {
      4.             if(reference.get() != null) {
      5.                 return reference.get();
      6.             }
      7.         }
      8.         final Handler handler = new Handler() {
      9.             public void handleMessage(final android.os.Message msg) {
      10.                 //加入到緩存中
      11.                 Bitmap bitmap = (Bitmap)msg.obj;
      12.                 imageMap.put(imageUrl, new SoftReference<Bitmap>(bitmap));
      13.                 if(imageCallBack != null) {
      14.                     imageCallBack.getBitmap(bitmap);
      15.                 }
      16.             }
      17.         };
      18.         new Thread(){
      19.             public void run() {
      20.                 Message message = handler.obtainMessage();
      21.                 message.obj = downloadBitmap(imageUrl);
      22.                 handler.sendMessage(message);
      23.             }
      24.         }.start();
      25.         return null ;
      26.     }

      27.     // 從網(wǎng)上下載圖片
      28.     private Bitmap downloadBitmap (String imageUrl) {
      29.         Bitmap bitmap = null;
      30.         try {
      31.             bitmap = BitmapFactory.decodeStream(new URL(imageUrl).openStream());
      32.             return bitmap ;
      33.         } catch (Exception e) {
      34.             e.printStackTrace();
      35.             return null;
      36.         } 
      37.     }
      1.     public interface ImageCallBack{
      2.         void getBitmap(Bitmap bitmap);
      3.     }


      2、內(nèi)存緩存技術(shù)
      另外一種圖片緩存的方式就是內(nèi)存緩存技術(shù)。在Android中,有一個(gè)叫做LruCache類專門用來做圖片緩存處理的。
      它有一個(gè)特點(diǎn),當(dāng)緩存的圖片達(dá)到了預(yù)先設(shè)定的值的時(shí)候,那么近期使用次數(shù)最少的圖片就會(huì)被回收掉。
      步驟:(1)要先設(shè)置緩存圖片的內(nèi)存大小,我這里設(shè)置為手機(jī)內(nèi)存的1/8,
                 手機(jī)內(nèi)存的獲取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory() / 1024);
            (2)LruCache里面的鍵值對(duì)分別是URL和對(duì)應(yīng)的圖片
            (3)重寫了一個(gè)叫做sizeOf的方法,返回的是圖片數(shù)量。

      1. private LruCache<String, Bitmap> mMemoryCache;
      2. private LruCacheUtils() {
      3.         if (mMemoryCache == null)
      4.             mMemoryCache = new LruCache<String, Bitmap>(
      5.                     MAXMEMONRY / 8) {
      6.                 @Override
      7.                 protected int sizeOf(String key, Bitmap bitmap) {
      8.                     // 重寫此方法來衡量每張圖片的大小,默認(rèn)返回圖片數(shù)量。
      9.                     return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
      10.                 }

      11.                 @Override
      12.                 protected void entryRemoved(boolean evicted, String key,
      13.                         Bitmap oldValue, Bitmap newValue) {
      14.                     Log.v("tag", "hard cache is full , push to soft cache");
      15.                    
      16.                 }
      17.             };
      18.     }
           (4)下面的方法分別是清空緩存、添加圖片到緩存、從緩存中取得圖片、從緩存中移除。
                移除和清除緩存是必須要做的事,因?yàn)閳D片緩存處理不當(dāng)就會(huì)報(bào)內(nèi)存溢出,所以一定要引起注意。
      1. public void clearCache() {
      2.         if (mMemoryCache != null) {
      3.             if (mMemoryCache.size() > 0) {
      4.                 Log.d("CacheUtils",
      5.                         "mMemoryCache.size() " + mMemoryCache.size());
      6.                 mMemoryCache.evictAll();
      7.                 Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
      8.             }
      9.             mMemoryCache = null;
      10.         }
      11.     }

      12.     public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
      13.         if (mMemoryCache.get(key) == null) {
      14.             if (key != null && bitmap != null)
      15.                 mMemoryCache.put(key, bitmap);
      16.         } else
      17.             Log.w(TAG, "the res is aready exits");
      18.     }

      19.     public synchronized Bitmap getBitmapFromMemCache(String key) {
      20.         Bitmap bm = mMemoryCache.get(key);
      21.         if (key != null) {
      22.             return bm;
      23.         }
      24.         return null;
      25.     }

      26.     /**
      27.      * 移除緩存
      28.      * 
      29.      * @param key
      30.      */
      31.     public synchronized void removeImageCache(String key) {
      32.         if (key != null) {
      33.             if (mMemoryCache != null) {
      34.                 Bitmap bm = mMemoryCache.remove(key);
      35.                 if (bm != null)
      36.                     bm.recycle();
      37.             }
      38.         }
      39.     }

      4、兩者的比
      說到這里,我覺得有必要來進(jìn)行一下比較了。
      網(wǎng)上有很多人使用軟引用加載圖片的多 ,但是現(xiàn)在已經(jīng)不再推薦使用這種方式了,
      (1)因?yàn)閺?Android 2.3 (API Level 9)開始,垃圾回收器會(huì)更傾向于回收持有軟引用或弱引用的對(duì)象,
           這讓軟引用和弱引用變得不再可靠。

      (2)另外,Android 3.0 (API Level 11)中,圖片的數(shù)據(jù)會(huì)存儲(chǔ)在本地的內(nèi)存當(dāng)中,
           因而無法用一種可預(yù)見的方式將其釋放,這就有潛在的風(fēng)險(xiǎn)造成應(yīng)用程序的內(nèi)存溢出并崩潰,

      所以我這里用得是LruCache來緩存圖片,當(dāng)存儲(chǔ)Image的大小大于LruCache設(shè)定的值,系統(tǒng)自動(dòng)釋放內(nèi)存,
      這個(gè)類是3.1版本中提供的,如果你是在更早的Android版本中開發(fā),則需要導(dǎo)入android-support-v4的jar包
      。

      后記:我一直有強(qiáng)調(diào)一件事件,就是人應(yīng)該要不停地進(jìn)步,沒有人生來就會(huì)編碼,
      更沒有人一開始就能找到很好的解決方案,
      我介紹了這兩種用法,其實(shí)就是想說,
      這些都是我的技術(shù)進(jìn)步的一個(gè)歷程。如果大家有好的建議或者有什么好的看法,

      記得提出來,很高興能和大家分享。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多