Created AsyncTask for loading miroguide thumbnails from the disk cache

This commit is contained in:
daniel oeh 2012-08-03 15:02:48 +02:00
parent 7ada4c2efb
commit 24775b9163
3 changed files with 109 additions and 55 deletions

View File

@ -90,7 +90,14 @@ public abstract class BitmapDecodeWorkerTask extends
R.drawable.default_cover); R.drawable.default_cover);
} }
protected abstract void storeBitmapInCache(Bitmap bitmap); protected void storeBitmapInCache(Bitmap bitmap) {
FeedImageLoader loader = FeedImageLoader.getInstance();
if (baseLength == LENGTH_BASE_COVER) {
loader.addBitmapToCoverCache(fileUrl, bitmap);
} else if (baseLength == LENGTH_BASE_THUMBNAIL) {
loader.addBitmapToThumbnailCache(fileUrl, bitmap);
}
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
public void executeAsync() { public void executeAsync() {

View File

@ -1,15 +1,25 @@
package de.danoeh.antennapod.asynctask; package de.danoeh.antennapod.asynctask;
import java.io.IOException;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.util.LruCache; import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView; import android.widget.ImageView;
import com.jakewharton.DiskLruCache;
import com.jakewharton.DiskLruCache.Snapshot;
import de.danoeh.antennapod.PodcastApp; import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.FeedImage; import de.danoeh.antennapod.feed.FeedImage;
import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.miroguide.model.MiroChannel;
import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.storage.DownloadRequester;
/** Caches and loads FeedImage bitmaps in the background */ /** Caches and loads FeedImage bitmaps in the background */
@ -20,6 +30,10 @@ public class FeedImageLoader {
public static final int LENGTH_BASE_COVER = 200; public static final int LENGTH_BASE_COVER = 200;
public static final int LENGTH_BASE_THUMBNAIL = 100; public static final int LENGTH_BASE_THUMBNAIL = 100;
private static final String CACHE_DIR = "miroguide_thumbnails";
private static final int CACHE_SIZE = 20 * 1024 * 1024;
private static final int VALUE_SIZE = 500 * 1024;
/** /**
* Stores references to loaded bitmaps. Bitmaps can be accessed by the id of * Stores references to loaded bitmaps. Bitmaps can be accessed by the id of
* the FeedImage the bitmap belongs to. * the FeedImage the bitmap belongs to.
@ -32,15 +46,15 @@ public class FeedImageLoader {
final int coverCacheSize = 1024 * 1024 * memClass / 10; final int coverCacheSize = 1024 * 1024 * memClass / 10;
final int thumbnailCacheSize = 1024 * 1024 * memClass / 6; final int thumbnailCacheSize = 1024 * 1024 * memClass / 6;
private LruCache<Long, Bitmap> coverCache; private LruCache<String, Bitmap> coverCache;
private LruCache<Long, Bitmap> thumbnailCache; private LruCache<String, Bitmap> thumbnailCache;
private FeedImageLoader() { private FeedImageLoader() {
coverCache = new LruCache<Long, Bitmap>(coverCacheSize) { coverCache = new LruCache<String, Bitmap>(coverCacheSize) {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Override @Override
protected int sizeOf(Long key, Bitmap value) { protected int sizeOf(String key, Bitmap value) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12) if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
return value.getByteCount(); return value.getByteCount();
else else
@ -50,11 +64,11 @@ public class FeedImageLoader {
}; };
thumbnailCache = new LruCache<Long, Bitmap>(thumbnailCacheSize) { thumbnailCache = new LruCache<String, Bitmap>(thumbnailCacheSize) {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Override @Override
protected int sizeOf(Long key, Bitmap value) { protected int sizeOf(String key, Bitmap value) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12) if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
return value.getByteCount(); return value.getByteCount();
else else
@ -72,9 +86,25 @@ public class FeedImageLoader {
return singleton; return singleton;
} }
public static DiskLruCache openThubmnailDiskCache() throws IOException {
Context appContext = PodcastApp.getInstance();
DiskLruCache cache = null;
try {
cache = DiskLruCache.open(
appContext.getExternalFilesDir(CACHE_DIR),
appContext.getPackageManager().getPackageInfo(
appContext.getPackageName(), 0).versionCode,
VALUE_SIZE, CACHE_SIZE);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return cache;
}
public void loadCoverBitmap(FeedImage image, ImageView target) { public void loadCoverBitmap(FeedImage image, ImageView target) {
if (image != null) { if (image.getFile_url() != null) {
Bitmap bitmap = getBitmapFromCoverCache(image.getId()); Bitmap bitmap = getBitmapFromCoverCache(image.getFile_url());
if (bitmap != null) { if (bitmap != null) {
target.setImageBitmap(bitmap); target.setImageBitmap(bitmap);
} else { } else {
@ -89,8 +119,8 @@ public class FeedImageLoader {
} }
public void loadThumbnailBitmap(FeedImage image, ImageView target) { public void loadThumbnailBitmap(FeedImage image, ImageView target) {
if (image != null) { if (image.getFile_url() != null) {
Bitmap bitmap = getBitmapFromThumbnailCache(image.getId()); Bitmap bitmap = getBitmapFromThumbnailCache(image.getFile_url());
if (bitmap != null) { if (bitmap != null) {
target.setImageBitmap(bitmap); target.setImageBitmap(bitmap);
} else { } else {
@ -110,27 +140,27 @@ public class FeedImageLoader {
} }
public boolean isInThumbnailCache(FeedImage image) { public boolean isInThumbnailCache(FeedImage image) {
return thumbnailCache.get(image.getId()) != null; return thumbnailCache.get(image.getFile_url()) != null;
} }
public Bitmap getBitmapFromThumbnailCache(long id) { public Bitmap getBitmapFromThumbnailCache(String key) {
return thumbnailCache.get(id); return thumbnailCache.get(key);
} }
public void addBitmapToThumbnailCache(long id, Bitmap bitmap) { public void addBitmapToThumbnailCache(String key, Bitmap bitmap) {
thumbnailCache.put(id, bitmap); thumbnailCache.put(key, bitmap);
} }
public boolean isInCoverCache(FeedImage image) { public boolean isInCoverCache(FeedImage image) {
return coverCache.get(image.getId()) != null; return coverCache.get(image.getFile_url()) != null;
} }
public Bitmap getBitmapFromCoverCache(long id) { public Bitmap getBitmapFromCoverCache(String key) {
return coverCache.get(id); return coverCache.get(key);
} }
public void addBitmapToCoverCache(long id, Bitmap bitmap) { public void addBitmapToCoverCache(String key, Bitmap bitmap) {
coverCache.put(id, bitmap); coverCache.put(key, bitmap);
} }
class FeedImageDecodeWorkerTask extends BitmapDecodeWorkerTask { class FeedImageDecodeWorkerTask extends BitmapDecodeWorkerTask {
@ -150,15 +180,6 @@ public class FeedImageLoader {
return target.getTag() == null || target.getTag() == image; return target.getTag() == null || target.getTag() == image;
} }
@Override
protected void storeBitmapInCache(Bitmap bitmap) {
if (baseLength == LENGTH_BASE_COVER) {
addBitmapToCoverCache(image.getId(), bitmap);
} else if (baseLength == LENGTH_BASE_THUMBNAIL) {
addBitmapToThumbnailCache(image.getId(), bitmap);
}
}
@Override @Override
protected void onInvalidFileUrl() { protected void onInvalidFileUrl() {
super.onInvalidFileUrl(); super.onInvalidFileUrl();
@ -173,4 +194,46 @@ public class FeedImageLoader {
} }
class MiroGuideDiskCacheLoader extends BitmapDecodeWorkerTask {
private static final String TAG = "MiroGuideDiskCacheLoader";
private Exception exception;
private MiroChannel channel;
public MiroGuideDiskCacheLoader(ImageView target, MiroChannel channel,
int length) {
super(target, channel.getThumbnailUrl(), length);
this.channel = channel;
}
@Override
protected Void doInBackground(Void... params) {
try {
DiskLruCache cache = openThubmnailDiskCache();
Snapshot snapshot = cache.get(fileUrl);
storeBitmapInCache(BitmapFactory.decodeStream(snapshot
.getInputStream(0)));
} catch (IOException e) {
e.printStackTrace();
exception = e;
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (exception != null) {
super.onPostExecute(result);
} else {
Log.e(TAG, "Failed to load bitmap from disk cache");
}
}
@Override
protected boolean tagsMatching(ImageView target) {
return target.getTag() == null || target.getTag() == channel;
}
}
} }

View File

@ -18,10 +18,7 @@ import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.miroguide.model.MiroChannel; import de.danoeh.antennapod.miroguide.model.MiroChannel;
import de.danoeh.antennapod.util.BitmapDecoder; import de.danoeh.antennapod.util.BitmapDecoder;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
import android.widget.ImageView; import android.widget.ImageView;
@ -29,12 +26,8 @@ import android.widget.ImageView;
public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask { public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
private static final String TAG = "MiroGuideThumbnailDownloader"; private static final String TAG = "MiroGuideThumbnailDownloader";
private static final String CACHE_DIR = "miroguide_thumbnails";
private static final int CACHE_SIZE = 20 * 1024 * 1024;
private static final int VALUE_SIZE = 500 * 1024;
private Exception exception; private Exception exception;
private MiroChannel miroChannel; private MiroChannel miroChannel;
public MiroGuideThumbnailDownloader(ImageView target, public MiroGuideThumbnailDownloader(ImageView target,
@ -43,14 +36,13 @@ public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
this.miroChannel = miroChannel; this.miroChannel = miroChannel;
} }
private static DiskLruCache openThubmnailDiskCache() @Override
throws NameNotFoundException, IOException { protected void onPostExecute(Void result) {
Context appContext = PodcastApp.getInstance(); if (exception != null) {
return DiskLruCache.open( super.onPostExecute(result);
appContext.getExternalFilesDir(CACHE_DIR), } else {
appContext.getPackageManager().getPackageInfo( Log.e(TAG, "Failed to download thumbnail");
appContext.getPackageName(), 0).versionCode, }
VALUE_SIZE, CACHE_SIZE);
} }
@Override @Override
@ -66,7 +58,7 @@ public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
File destination = new File(PodcastApp.getInstance().getCacheDir(), File destination = new File(PodcastApp.getInstance().getCacheDir(),
Integer.toString(fileUrl.hashCode())); Integer.toString(fileUrl.hashCode()));
try { try {
DiskLruCache diskCache = openThubmnailDiskCache(); DiskLruCache diskCache = FeedImageLoader.openThubmnailDiskCache();
Editor editor = diskCache.edit(fileUrl); Editor editor = diskCache.edit(fileUrl);
if (editor != null) { if (editor != null) {
HttpURLConnection connection = (HttpURLConnection) url HttpURLConnection connection = (HttpURLConnection) url
@ -100,9 +92,6 @@ public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} catch (NameNotFoundException e) {
e.printStackTrace();
return null;
} finally { } finally {
if (destination.exists()) { if (destination.exists()) {
destination.delete(); destination.delete();
@ -115,9 +104,4 @@ public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
protected boolean tagsMatching(ImageView target) { protected boolean tagsMatching(ImageView target) {
return target.getTag() == null || target.getTag() == miroChannel; return target.getTag() == null || target.getTag() == miroChannel;
} }
@Override
protected void storeBitmapInCache(Bitmap bitmap) {
}
} }