2

在从当前用户的设备相机或图库获取或获取照片之后,如何实施下一个StoreImage方法? (使用Android Universal Image Loader如何在内存中缓存内存和磁盘缓存中的位图?

#region IImageManager 

// Stores the given bitmap inside both memory and disc caches... 
public override void StoreImage (object rawImage, string key, bool toDisc) 
{ 
    // Given key examples: 
    // local_photo_66831.jpg 
    // local_thumbnail_photo_66831.jpg 

    string uri = MakeUri (key); 

    // Returned uri examples: 
    // file:///storage/sdcard0/Android/data/com.xxx.xxx/cache/local_photo_66831.jpg 
    // file:///storage/sdcard0/Android/data/com.xxx.xxx/cache/local_thumbnail_photo_66831.jpg 

    ImageLoader.Instance.MemoryCache.Put (uri, (Bitmap)rawImage); 

    if (toDisc) 
     ImageLoader.Instance.DiscCache.Put (uri, <File>); 
} 

问题:

  • 我如何保存DiscCache里面的内存当前位图?
  • 以编程方式将文件添加到DiscCache而不是使用​​方法加载文件可以吗?
  • 是否有可能用简单的字符串*工作关键 * s,而不是总是创建本地* URI * S,然后使用像“ImageLoader.Instance.MemoryCache.Get(密钥)”的调用访问它们?

我想端口接下来的iOS - SDWebImage实施了类似的Android - UIL版本:

public override void StoreImage (object rawImage, string key, bool toDisk) 
{ 
    SDWebImageManager.SharedManager.ImageCache.StoreImage ((UIImage)rawImage, key, toDisk); 
} 

在此先感谢。

+0

你找到一个解决的办法?我也使用UIL,但在他们的[github页面](https://github.com/nostra13/Android-Universal-Image-Loader)上看到他们不推荐它显示本地绘图。所以我尝试从[显示位图高效](http://developer.android.com/training/displaying-bitmaps/index.html)实施BitmapFun示例,但有一些麻烦定制它为谷歌标记使用。你只是为了缓存而使用UIL的想法听起来很有趣。 – AsafK

回答

3

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

希望你会得到一些想法,从上面的代码提示..

+0

请问使用上述课程。我所知道的是,要同时使用磁盘和内存缓存,您必须遵循以下算法:尝试从mem缓存加载,如果不可用,请尝试从磁盘缓存加载,如果所有其他尝试都尝试从Internet加载。我恳请3个代码片段实现上述3个目标 – iOSAndroidWindowsMobileAppsDev

+0

另外,我可以问问什么是存储顺序 - 请确认您先保存到缓存然后再保存到磁盘缓存 – iOSAndroidWindowsMobileAppsDev