Load new bitmap if imageview's size has become larger

This commit is contained in:
daniel oeh 2012-10-14 13:50:05 +02:00
parent 9eef78109f
commit a62cf5d14c
4 changed files with 66 additions and 157 deletions

View File

@ -20,8 +20,7 @@ public abstract class BitmapDecodeWorkerTask extends Thread {
private static final String TAG = "BitmapDecodeWorkerTask";
private ImageView target;
protected Bitmap bitmap;
private Bitmap decodedBitmap;
protected CachedBitmap cBitmap;
protected String fileUrl;
@ -45,8 +44,8 @@ public abstract class BitmapDecodeWorkerTask extends Thread {
protected void onPostExecute() {
// check if imageview is still supposed to display this image
if (tagsMatching(target) && bitmap != null) {
target.setImageBitmap(bitmap);
if (tagsMatching(target) && cBitmap.getBitmap() != null) {
target.setImageBitmap(cBitmap.getBitmap());
} else {
if (AppConfig.DEBUG)
Log.d(TAG, "Not displaying image");
@ -60,13 +59,13 @@ public abstract class BitmapDecodeWorkerTask extends Thread {
f = new File(fileUrl);
}
if (fileUrl != null && f.exists()) {
bitmap = BitmapDecoder.decodeBitmap(PREFERRED_LENGTH, fileUrl);
if (bitmap != null) {
storeBitmapInCache(bitmap);
cBitmap = new CachedBitmap(BitmapDecoder.decodeBitmap(PREFERRED_LENGTH, fileUrl), PREFERRED_LENGTH);
if (cBitmap.getBitmap() != null) {
storeBitmapInCache(cBitmap);
} else {
Log.w(TAG, "Could not load bitmap. Using default image.");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
cBitmap = new CachedBitmap(BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover), PREFERRED_LENGTH);
}
if (AppConfig.DEBUG)
Log.d(TAG, "Finished loading bitmaps");
@ -94,16 +93,16 @@ public abstract class BitmapDecodeWorkerTask extends Thread {
protected void onInvalidFileUrl() {
Log.e(TAG, "FeedImage has no valid file url. Using default image");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
cBitmap = new CachedBitmap(BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover), PREFERRED_LENGTH);
}
protected void storeBitmapInCache(Bitmap bitmap) {
protected void storeBitmapInCache(CachedBitmap cb) {
FeedImageLoader loader = FeedImageLoader.getInstance();
if (imageType == FeedImageLoader.IMAGE_TYPE_COVER) {
loader.addBitmapToCoverCache(fileUrl, bitmap);
loader.addBitmapToCoverCache(fileUrl, cb);
} else if (imageType == FeedImageLoader.IMAGE_TYPE_THUMBNAIL) {
loader.addBitmapToThumbnailCache(fileUrl, bitmap);
loader.addBitmapToThumbnailCache(fileUrl, cb);
}
}
}

View File

@ -0,0 +1,27 @@
package de.danoeh.antennapod.asynctask;
import android.graphics.Bitmap;
/** Stores a bitmap and the length it was decoded with. */
public class CachedBitmap {
private Bitmap bitmap;
private int length;
public CachedBitmap(Bitmap bitmap, int length) {
super();
this.bitmap = bitmap;
this.length = length;
}
public Bitmap getBitmap() {
return bitmap;
}
public int getLength() {
return length;
}
}

View File

@ -28,10 +28,6 @@ public class FeedImageLoader {
public static final int IMAGE_TYPE_THUMBNAIL = 0;
public static final int IMAGE_TYPE_COVER = 1;
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 Handler handler;
private ExecutorService executor;
@ -47,36 +43,38 @@ public class FeedImageLoader {
final int coverCacheSize = 1024 * 1024 * memClass / 8;
final int thumbnailCacheSize = 1024 * 1024 * memClass / 8;
private LruCache<String, Bitmap> coverCache;
private LruCache<String, Bitmap> thumbnailCache;
private LruCache<String, CachedBitmap> coverCache;
private LruCache<String, CachedBitmap> thumbnailCache;
private FeedImageLoader() {
handler = new Handler();
executor = createExecutor();
coverCache = new LruCache<String, Bitmap>(coverCacheSize) {
coverCache = new LruCache<String, CachedBitmap>(coverCacheSize) {
@SuppressLint("NewApi")
@Override
protected int sizeOf(String key, Bitmap value) {
protected int sizeOf(String key, CachedBitmap value) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
return value.getByteCount();
return value.getBitmap().getByteCount();
else
return (value.getRowBytes() * value.getHeight());
return (value.getBitmap().getRowBytes() * value.getBitmap()
.getHeight());
}
};
thumbnailCache = new LruCache<String, Bitmap>(thumbnailCacheSize) {
thumbnailCache = new LruCache<String, CachedBitmap>(thumbnailCacheSize) {
@SuppressLint("NewApi")
@Override
protected int sizeOf(String key, Bitmap value) {
protected int sizeOf(String key, CachedBitmap value) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
return value.getByteCount();
return value.getBitmap().getByteCount();
else
return (value.getRowBytes() * value.getHeight());
return (value.getBitmap().getRowBytes() * value.getBitmap()
.getHeight());
}
@ -121,9 +119,9 @@ public class FeedImageLoader {
*/
public void loadCoverBitmap(FeedImage image, ImageView target, int length) {
if (image != null && image.getFile_url() != null) {
Bitmap bitmap = getBitmapFromCoverCache(image.getFile_url());
if (bitmap != null) {
target.setImageBitmap(bitmap);
CachedBitmap cBitmap = getBitmapFromCoverCache(image.getFile_url());
if (cBitmap != null && cBitmap.getLength() >= length) {
target.setImageBitmap(cBitmap.getBitmap());
} else {
target.setImageResource(R.drawable.default_cover);
FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
@ -144,23 +142,23 @@ public class FeedImageLoader {
public void loadThumbnailBitmap(FeedImage image, ImageView target) {
loadThumbnailBitmap(image, target, target.getHeight());
}
/**
* Load a bitmap from the thumbnail cache. If the bitmap is not in the
* cache, it will be loaded from the disk. This method should either be
* called if the ImageView's size has already been set or inside a Runnable
* which is posted to the ImageView's message queue.
*/
public void loadThumbnailBitmap(FeedImage image, ImageView target, int length) {
public void loadThumbnailBitmap(FeedImage image, ImageView target,
int length) {
if (image != null && image.getFile_url() != null) {
Bitmap bitmap = getBitmapFromThumbnailCache(image.getFile_url());
if (bitmap != null) {
target.setImageBitmap(bitmap);
CachedBitmap cBitmap = getBitmapFromThumbnailCache(image.getFile_url());
if (cBitmap != null && cBitmap.getLength() >= length) {
target.setImageBitmap(cBitmap.getBitmap());
} else {
target.setImageResource(R.drawable.default_cover);
FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
handler, target, image, length,
IMAGE_TYPE_THUMBNAIL);
handler, target, image, length, IMAGE_TYPE_THUMBNAIL);
executor.submit(worker);
}
} else {
@ -168,26 +166,6 @@ public class FeedImageLoader {
}
}
public void loadMiroGuideThumbnail(MiroGuideChannel channel,
ImageView target) {
if (channel.getThumbnailUrl() != null) {
Bitmap bitmap = getBitmapFromThumbnailCache(channel
.getThumbnailUrl());
if (bitmap == null) {
if (AppConfig.DEBUG)
Log.d(TAG, "Starting new thumbnail download");
target.setImageResource(R.drawable.default_cover);
executor.submit(new MiroGuideThumbnailDownloader(handler,
target, channel, target.getHeight(), coverCacheSize));
} else {
target.setImageBitmap(bitmap);
}
} else {
target.setImageResource(R.drawable.default_cover);
}
}
public void clearExecutorQueue() {
executor.shutdownNow();
if (AppConfig.DEBUG)
@ -205,11 +183,11 @@ public class FeedImageLoader {
return thumbnailCache.get(image.getFile_url()) != null;
}
public Bitmap getBitmapFromThumbnailCache(String key) {
private CachedBitmap getBitmapFromThumbnailCache(String key) {
return thumbnailCache.get(key);
}
public void addBitmapToThumbnailCache(String key, Bitmap bitmap) {
public void addBitmapToThumbnailCache(String key, CachedBitmap bitmap) {
thumbnailCache.put(key, bitmap);
}
@ -217,11 +195,11 @@ public class FeedImageLoader {
return coverCache.get(image.getFile_url()) != null;
}
public Bitmap getBitmapFromCoverCache(String key) {
private CachedBitmap getBitmapFromCoverCache(String key) {
return coverCache.get(key);
}
public void addBitmapToCoverCache(String key, Bitmap bitmap) {
public void addBitmapToCoverCache(String key, CachedBitmap bitmap) {
coverCache.put(key, bitmap);
}

View File

@ -1,95 +0,0 @@
package de.danoeh.antennapod.asynctask;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.miroguide.model.MiroGuideChannel;
import de.danoeh.antennapod.util.BitmapDecoder;
/** Downlods thumbnails from the MiroGuide and stores them in a DiskLruCache */
public class MiroGuideThumbnailDownloader extends BitmapDecodeWorkerTask {
private static final String TAG = "MiroGuideThumbnailDownloader";
private Exception exception;
private MiroGuideChannel miroChannel;
public MiroGuideThumbnailDownloader(Handler handler, ImageView target,
MiroGuideChannel miroChannel, int length, int imageType) {
super(handler, target, miroChannel.getThumbnailUrl(), length, imageType);
this.miroChannel = miroChannel;
}
@Override
protected void onPostExecute() {
if (exception == null) {
super.onPostExecute();
} else {
Log.e(TAG, "Failed to download thumbnail");
}
}
public void run() {
// Download file to cache folder
URL url = null;
try {
url = new URL(fileUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
endBackgroundTask();
}
File destination = new File(PodcastApp.getInstance().getCacheDir(),
Integer.toString(fileUrl.hashCode()));
try {
if (AppConfig.DEBUG)
Log.d(TAG, "Downloading " + fileUrl);
URLConnection connection = url.openConnection();
connection.connect();
byte inputBuffer[] = new byte[1024];
BufferedInputStream input = new BufferedInputStream(
connection.getInputStream());
FileOutputStream output = new FileOutputStream(destination);
int count = 0;
while ((count = input.read(inputBuffer)) != -1) {
output.write(inputBuffer, 0, count);
}
output.close();
if (AppConfig.DEBUG)
Log.d(TAG, "MiroGuide thumbnail downloaded");
// Get a smaller version of the bitmap and store it inside the
// LRU
// Cache
bitmap = BitmapDecoder.decodeBitmap(PREFERRED_LENGTH,
destination.getPath());
if (bitmap != null) {
storeBitmapInCache(bitmap);
}
} catch (IOException e) {
e.printStackTrace();
miroChannel.setThumbnailUrl(null);
endBackgroundTask();
} finally {
if (destination.exists()) {
destination.delete();
}
}
endBackgroundTask();
}
@Override
protected boolean tagsMatching(ImageView target) {
return target.getTag() == miroChannel;
}
}