2010-11-26 32 views
2

我使用圖像下載邏輯從網頁顯示圖像,我只想在第一時間下載圖像,下次不要從網上下載圖像,因爲第一次下載圖像存儲在高速緩衝存儲器中,所以我從捕捉內存中顯示圖像,如果不在高速緩衝存儲器中退出那個圖像,否則下載不需要從網上下載那個圖像,怎麼可能?如何使用緩衝存儲器進行圖像下載?

感謝朋友。

回答

0

我不是一個Android開發人員,但我相信應該有一種方法來寫入本地內存。 I.e寫入目錄。我猜想圖像是以字節數組的形式從網絡返回的,您可以將其保存到本地內存。然後,只要再次需要,您可以將其讀回。

0

您可以實現用一個Hashtable緩存「的CacheManager」單例類,所以當你下載完成添加到緩存中的對象做cache.put(IMAGEURL,ImageView的)。必須在單例中執行此操作才能在應用程序生命週期中獲得緩存。

+1

不要這樣做。將ImageView保存在一個單獨的Hashtable中會導致內存泄漏並最終導致應用程序崩潰(通常是隱藏的「位圖超出VM預算」。)緩存文件中的位圖或字節,理想情況下使用WeakReferences,但永遠不會保存Drawables或Views(至少如果您的緩存持續存在於各個活動中),因爲它們保持對其包含的上下文的引用,這將保持原始包含的活動不被垃圾收集。看到這個Android開發人員的文章更多的:http://developer.android.com/resources/articles/avoiding-memory-leaks.html – 2010-11-26 17:13:00

+0

是的,你是對的,我快速回答這個問題,沒有想到這種行爲,我總是使用自定義普通pojos做這個'緩存',但從來沒有使用ImageViews,所以我的appologies。 – Franco 2010-11-26 17:36:21

1

如果您不想在這裏重新發明輪子,您可以使用droid-fu的圖像加載內置緩存,也可以深入瞭解cachefu類以瞭解更多信息。特別是,AbstractCache是兩級緩存的良好基礎;在這種情況下,它保持較小的內存緩存,並且如果SD卡可用,它將保持額外的存在。

2

下面的ImageLoader的類來維持高速緩存內存和磁盤存儲到圖像存儲在盤下載後的圖像。

public class MyImageLoader { 

private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB 
private static final String DISK_CACHE_SUBDIR = "ImageCache"; 
private DiskLruImageCache mDiskLruImageCache; 
private ExecutorService executorService; 
private LruCache<String, Bitmap> mMemoryCache; 
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); 
private int byteCounts; 
private int requiredHeight = 100, requiredWidth = 100; // setting default height & width as 100 
private final int default_icon = R.drawable.no_image_friend; 
CommonMethod mCommonMethod; 

public MyImageLoader(Context context) { 

    executorService = Executors.newFixedThreadPool(2); 
    final int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); 
    // Use 1/8th of the available memory for this memory cache. 
    final int cacheSize = 1024 * 1024 * memClass/8; 

    mCommonMethod = new CommonMethod(context); 
    mDiskLruImageCache = new DiskLruImageCache(context, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE, CompressFormat.PNG, 70); 

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 

     @Override 
     protected int sizeOf(String key, Bitmap bitmap) { 
      byteCounts = bitmap.getRowBytes() * bitmap.getHeight(); 
      return byteCounts; 
     } 
    }; 
} 

public void ExecuteLoading(String urlString, ImageView mImageView) { 

    imageViews.put(mImageView, urlString); 
    Bitmap bitmap = getBitmapFromMemCache(urlString); 

    if (bitmap != null){ 
     mImageView.setImageBitmap(bitmap); 
    } 
    else { 
     executorService.submit(new LoadImages(urlString, mImageView)); 
     mImageView.setImageResource(default_icon); 
    } 
} 

boolean ImageViewReused(String urlString, ImageView mImageView){ 
    String tag=imageViews.get(mImageView); 
    if(tag==null || !tag.equals(urlString)) 
     return true; 
    return false; 
} 

class LoadImages implements Runnable { 
    String urlString; 
    ImageView mImageView; 
    DisplayImages images; 

    public LoadImages(String urlString, ImageView mImageView) { 
     this.urlString = urlString; 
     this.mImageView = mImageView; 
    } 

    public void run() { 

     if(!ImageViewReused(urlString, mImageView)){ 
      Bitmap bitmap = DownloadFromUrl(urlString); 

      Bitmap mBitmapMask = mCommonMethod.makeMaskImageCrop(bitmap, R.drawable.image_thumb_mask, R.drawable.image_thumb); 

      //TODO to mask image then bitmap pass 
      addBitmapToDiskCache(urlString, mBitmapMask); 

      DisplayImages images = new DisplayImages(urlString, mImageView, mBitmapMask); 
      ((Activity) mImageView.getContext()).runOnUiThread(images); 
     } 
    } 
} 

class DisplayImages implements Runnable { 
    Bitmap bitmap; 
    String urlString; 
    ImageView mImageView; 

    public DisplayImages(String urlString, ImageView mImageView, Bitmap bitmap) { 
     this.urlString = urlString; 
     this.mImageView = mImageView; 
     this.bitmap = bitmap; 
    } 

    public void run() { 

     if(!ImageViewReused(urlString, mImageView)){ 
      if (bitmap != null) 
       mImageView.setImageBitmap(bitmap); 
      else 
       mImageView.setImageResource(default_icon); 
     } 
    } 
} 

private Bitmap DownloadFromUrl(String urlString) { 
    return decodeBitmapFromStream(urlString, getReqiredWidth(), getRequiredHeight()); 
} 

private void addBitmapToMemoryCache(String key, Bitmap bitmap) { 
    synchronized (mMemoryCache) { 
     if (mMemoryCache.get(key) == null) { 
      mMemoryCache.put(key, bitmap); 
     } 
    } 
} 
private Bitmap getBitmapFromMemCache(String key) { 
    Bitmap bitmap = mMemoryCache.get(key); 
    if(bitmap == null){ 
     bitmap = getBitmapFromDiskCache(key); 
    } 
    return bitmap; 
} 

private void addBitmapToDiskCache(String key, Bitmap bitmap) { 
    synchronized (mDiskLruImageCache) { 
     if (!mDiskLruImageCache.containsKey(String.valueOf(key.hashCode()))) { 
      mDiskLruImageCache.put(String.valueOf(key.hashCode()), bitmap); 
      addBitmapToMemoryCache(key, bitmap); 
     } 
    } 
} 

private Bitmap getBitmapFromDiskCache(String key) { 
    return mDiskLruImageCache.getBitmap(String.valueOf(key.hashCode())); 
} 


private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    inSampleSize = Math.min(width/reqWidth, height/reqHeight); 

    return inSampleSize; 
} 

private static Bitmap decodeBitmapFromStream(String urlString, int reqWidth, int reqHeight) { 

    URL url = null; 
    InputStream is = null; 
    try { 
     url = new URL(urlString); 
     is = (InputStream) url.getContent(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeStream(is, null, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // As InputStream can be used only once we have to regenerate it again. 
    try { 
     is = (InputStream) url.getContent(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeStream(is, null, options); 
} 

public int getRequiredHeight() { 
    return requiredHeight; 
} 

public void setRequiredHeight(int longest, int requiredHeight) { 
    this.requiredHeight = requiredHeight > longest ? longest : requiredHeight; 
} 

public int getReqiredWidth() { 
    return requiredWidth; 
} 

public void setReqiredWidth(int longest, int requiredWidth) { 
    this.requiredWidth = requiredWidth > longest ? longest : requiredWidth; 
} 

public void clearCacheMemory() { 
    if(mMemoryCache.size() > 0){ 
     mMemoryCache.evictAll(); 
    } 
} 

public void clearDiskMemory() { 
    mDiskLruImageCache.clearCache(); 
} 
} 

希望你會得到一些想法,從上面的代碼提示..

相關問題