2010-11-26 3 views
2

イメージダウンロードロジックを使用してイメージを表示しています。最初にイメージをダウンロードします。次回はイメージをダウンロードしません。キャッシュメモリに初めてイメージストアをダウンロードするので、キャッシュメモリにそのイメージを残していない場合は、それ以外の場合はWebからそのイメージをダウンロードする必要はありません。どうすれば可能ですか?イメージダウンロードにキャッシュメモリを使用するには?

ありがとうございました。

答えて

0

私はアンドロイドデベロッパーではありませんが、ローカルメモリに書き込む方法があるはずです。私はディレクトリに書き込みます。私はあなたがローカルのmemに保存することができますバイトの配列として、Webから画像が戻って来ると思います。それで、もう一度それが必要なときにはいつでも、それを読んで戻すことができます。

0

ハッシュテーブルキャッシュを持つ「CacheManager」シングルトンクラスを実装できます。ダウンロードが完了したら、cache.put(imageUrl、imageView)を実行しているキャッシュオブジェクトに追加が完了します。アプリケーションライフサイクルでキャッシュを維持するには、これをシングルトンで行う必要があります。

+1

..あなたはいくつかのアイデアを取得し、上記のコードからヒントを願っています。 ImageViewsをシングルトンHashtableに保存するとメモリリークが発生し、最終的にアプリケーションのクラッシュが発生します(通常、ビットマップはVM予算を超えています)。WeakReferencesを使用するのが理想的ですが、キャッシュがアクティビティー間で永続的である場合)、そのコンテクストへの参照が維持されるため、最初に含まれていたアクティビティがガベージコレクションされないようになります。この詳細については、このアンドロイドの開発者の記事を参照してください:http://developer.android.com/resources/articles/avoiding-memory-leaks.html –

+0

はい、あなたは正しいです、私はすぐにその行動を考えることなく質問に答える、私はいつもこの「キャッシュ」をカスタムプレーンポーズで行いますが、ImageViewsでは決して行いません。 – Franco

1

ここでホイールを再開発したくないのであれば、droid-fuの画像読み込み機能を内蔵しているか、詳細についてはcachefuクラスを詳しく調べてください。特に、AbstractCacheは、2レベルのキャッシュに適しています。この場合、メモリ内のキャッシュを小さく保ち、SDカードが利用可能であれば、そこに余分なスペースを確保します。

2

imageLoaderクラスの下にはうまく動作しているようですし、両方のメモリやSDカードのキャッシングをサポートしています。

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キャッシュからロードしてください。利用できない場合はディスクキャッシュからロードしてみてください。上記の3つの目標を達成するために3つのコードスニペットをリクエストしています \t \t また、ストレージの順序がわかりますか?まずmemキャッシュに保存してからディスクキャッシュに保存してください – iOSAndroidWindowsMobileAppsDev

関連する問題