圖片緩衝策略

來源:互聯網
上載者:User

標籤:des   android   style   blog   http   color   使用   os   

圖片緩衝策略

1、圖片緩衝策略分析

從網路上載入一張圖,然後把它顯示到UI上是個很簡單的事情。當圖片變多時,處理起來就有些麻煩了,很典型的應用情境,如ListView,GridView或者ViePager等。我們既需要保證使用者看到更多的圖片,以免螢幕出現大面積的空白,又要保證記憶體能Hold住。

GC會自動釋放一個沒有強引用的圖片或者View,這本來是個好事情,但為了讓使用者來復原動時還能快速載入老圖片,通常會使用圖片緩衝。

下面分別討論下,通過使用Memory Cache和Disk Cache來增加UI的響應速度和流暢度。

 

一、使用Memory Cache

Memory Cache花費定量的記憶體來換取對圖片的快速存取。可以使用LruCache來快速實現。過去,我們通常使用SoftReference或WeakReference來實現Memory Cache,但是在Android 2.3 (API Level 9)之後,GC對SoftReference和WeakReference回收的更快,所以,SoftReference和WeakReference的效果就很差了。而且,在Android 3.0 (API Level 11)之前,Bitmap的像素資料存放在Native Memory中,如何釋放是不確定的,存在著記憶體流失,甚至Crash的風險。

為了確定LruCache的大小,我們需要參考如下幾個因素:

1、當前進程的剩餘記憶體有多少

2、為了保證良好的使用者體驗,應用情境顯示多少張圖片可以滿足要求?

3、螢幕的density是多少?不同像素的螢幕對圖片品質的要求是不一樣的,可以據此在取圖時做一些最佳化。

4、圖片被訪問的頻率是否相差很多?如果是這樣的話可以存放在不同的LruCache中。

5、有時需要在數量和品質之間做一些平衡。比如為圖片列表在Memory Cache中緩衝

較多的縮圖,在UI中先顯示縮圖,然後在後台載入一張高清的。

 

這裡沒有一個精確的數字來做為指導,需要我們在實際中就以上幾個因素進行權衡,設定合適的值。至於如何使用LruCache可以參考Support Library中的Demo。

二、使用Disk Cache

Memory Cache可以加快圖片的訪問速度,但記憶體有限,不可能所有圖片都放在Memory Cache中。當程式先被擠出記憶體,後又被重新啟動時,圖片仍需要重新擷取。這個時候,可以應用Disk Cache來緩衝圖片,圖片就不需要從網路上擷取了,節省了流量,減少了擷取時間。但需要注意,Disk Cache的讀取涉及到本地IO操作,需要開啟後台線程操作。

我們可以像系統Gallery那樣使用ContentProvider。另外,Disk Cache也可以很簡單地通過Android源碼中提供的DiskLruCache來實現。

 

2、圖片緩衝實現

一、記憶體緩衝

//需要匯入外部jar檔案 android-support-v4.jar

 importandroid.support.v4.util.LruCache;

 //開闢8M硬緩衝空間

private final int hardCachedSize =8*1024*1024;  

 

//hardcache 強引用

private final LruCache<String,Bitmap> sHardBitmapCache = new LruCache<String, Bitmap>(hardCachedSize)

{

  @Override

  public int sizeOf(Stringkey, Bitmap value)

  {

         return value.getRowBytes() *value.getHeight();
    }

 

  @Override

  protected voidentryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue)

  {

    Log.v("tag","hard cache is full , push to soft cache");
      

    //硬引用緩衝區滿,將一個最不經常使用的oldvalue推入到軟引用緩衝區

    sSoftBitmapCahe.put(key,new SoftReference<Bitmap>(oldValue));

   }

}

 

//軟引用

 private static final intSOFT_CACHE_CAPACITY = 40;

private final static LinkedHashMap<String,SoftReference<Bitmap>> sSoftBitmapCache = new  LinkedHashMao<String,SoftReference<Bitmap>>(SOFT_CACHE_CAPACITY, 0.75f, true)

{

  @Override

  publicSoftReference<Bitmap> put(String key, SoftReference<Bitmap> value)

  {

    returnsuper.input(key, value);

   }

  @Override

  protectedboolean removeEldestEntry(LinkedHashMap.Entry<Stirng,SoftReference<Bitmap>> eldest)

  {

    if(size() >SOFT_CACHE_CAPACITY)

    {

      Log.v("tag","Soft Reference limit , purge one");

      return true;

    }

  return false;

  }

 }

 

 

 //緩衝bitmap

public boolean putBitmap(String key,Bitmap bitmap)

{

  if(bitmap !=null)

  {

    synchronized(sHardBitmapCache)

    {

      sHardBitmapCache.put(key,bitmap);

    }

    return true;

  }  

  return false;
 }

 

//從緩衝中擷取bitmap

public Bitmap getBitmap(String key)

{

  synchronized(sHardBitmapCache)

  {

    final Bitmapbitmap = sHardBitmapCache.get(key);

    if(bitmap !=null)

    {

      return bitmap;

    }

  }

   //硬引用緩衝區間中讀取失敗,從軟引用緩衝區間讀取

  synchronized(sSoftBitmapCache)

  {

    SoftReference<Bitmap>bitmapReference = sSoftBtimapCache.get(key);
    if(bitmapReference != null)

    {

      final Bitmapbitmap2 = bitmapReference.get();

      if(bitmap2 !=null)

      {

        return bitmap2;

      }

      else

      {
                  Log.v("tag","soft reference 已經被回收");

        sSoftBitmapCache.remove(key);

      }

    }

   }

  return null;

 }

 

 

二、磁碟檔案快取

private File mCacheDir = context.getCacheDir();

private static final int MAX_CACHE_SIZE = 20 * 1024 * 1024; //20M

private final LruCache<String, Long> sFileCache = new LruCache<String, Long>(MAX_CACHE_SIZE)

{

  @Override
      public int sizeOf(Stringkey, Long value)

  {

    return value.intValue();

  }
  

  @Override

  protected void entryRemoved(booleanevicted, String key, Long oldValue, Long newValue)

  {

    File file = getFile(key);

    if(file != null)

    {

      file.delete();

    }

   }

 

  private File getFile(String fileName)throws FileNotFoundException

  {

    File file = new File(mCacheDir, fileName);

    if(!file.exists() || !file.isFile())

    {

             thrownew FileNotFoundException("檔案不存在或有同名檔案夾");

    }

    return file;

   }

 

  //緩衝bitmap到外部儲存

  public boolean putBitmap(String key, Bitmapbitmap)

  {

    File file = getFile(key);

    if(file != null)

    {

       Log.v("tag", "檔案已經存在");

      return true;

     }

    FileOutputStream fos =getOutputStream(key);

    boolean saved = bitmap.compress(CompressFormat.JPEG,100, fos);

    fos.flush();

    fos.close();

    if(saved)

    {

      synchronized(sFileCache)

      {

         sFileCache.put(key,getFile(key).length());

       }

      return true; 

    }

    return false;

   }

 

   //根據key擷取OutputStream

  private FileOutputStreamgetOutputStream(String key)

  {

    if(mCacheDir == null)

    return null;

    FileOutputStream fos = newFileOutputStream(mCacheDir.getAbsolutePath() + File.separator + key);

    return fos;

  }

 

  //擷取bitmap

  private static BitmapFactory.OptionssBitmapOptions;

  static

  {

    sBitmapOptions = newBitmapFactory.Options();

    sBitmapOptions.inPurgeable=true; //bitmapcan be purged to disk
   }

 

  public Bitmap getBitmap(String key)

  {

    File bitmapFile = getFile(key);

    if(bitmapFile != null)

    {

      Bitmap bitmap =BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null,sBitmapOptions);

            if(bitmap!= null)

     {

        //重新將其緩衝至硬引用中

        ...

      }

         }

  }

}

 
摘自: android讀取大圖片並緩衝 http://www.cnblogs.com/leehongee/p/3323837.html 圖片緩衝實現策略分析  http://blog.csdn.net/a345017062/article/details/8753649  

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.