split image cache into thumbnail- and cover-cache
This commit is contained in:
parent
74b1fac152
commit
d593d12e23
|
@ -48,7 +48,7 @@ public class FeedInfoActivity extends SherlockActivity {
|
|||
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
|
||||
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
|
||||
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
|
||||
FeedImageLoader.getInstance().loadBitmap(feed.getImage(), imgvCover);
|
||||
FeedImageLoader.getInstance().loadCoverBitmap(feed.getImage(), imgvCover);
|
||||
|
||||
txtvTitle.setText(feed.getTitle());
|
||||
txtvDescription.setText(feed.getDescription());
|
||||
|
|
|
@ -92,9 +92,9 @@ public class FeedlistAdapter extends ArrayAdapter<Feed> {
|
|||
} else {
|
||||
holder.newEpisodes.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
imageLoader.loadBitmap(feed.getImage(), holder.image);
|
||||
|
||||
holder.image.setTag(feed.getImage());
|
||||
imageLoader.loadThumbnailBitmap(feed.getImage(), holder.image);
|
||||
|
||||
// TODO find new Episodes txtvNewEpisodes.setText(feed)
|
||||
return convertView;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class SearchlistAdapter extends ArrayAdapter<SearchResult> {
|
|||
Feed feed = (Feed) component;
|
||||
holder.title.setText(feed.getTitle());
|
||||
holder.subtitle.setVisibility(View.GONE);
|
||||
FeedImageLoader.getInstance().loadBitmap(feed.getImage(),
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(feed.getImage(),
|
||||
holder.cover);
|
||||
|
||||
} else if (component.getClass() == FeedItem.class) {
|
||||
|
@ -61,7 +61,7 @@ public class SearchlistAdapter extends ArrayAdapter<SearchResult> {
|
|||
holder.subtitle.setVisibility(View.VISIBLE);
|
||||
holder.subtitle.setText(result.getSubtitle());
|
||||
}
|
||||
FeedImageLoader.getInstance().loadBitmap(item.getFeed().getImage(),
|
||||
FeedImageLoader.getInstance().loadThumbnailBitmap(item.getFeed().getImage(),
|
||||
holder.cover);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ public class FeedImageLoader {
|
|||
private static final String TAG = "FeedImageLoader";
|
||||
private static FeedImageLoader singleton;
|
||||
|
||||
public static final int LENGTH_BASE_COVER = 200;
|
||||
public static final int LENGTH_BASE_THUMBNAIL = 100;
|
||||
|
||||
/**
|
||||
* Stores references to loaded bitmaps. Bitmaps can be accessed by the id of
|
||||
* the FeedImage the bitmap belongs to.
|
||||
|
@ -32,12 +35,28 @@ public class FeedImageLoader {
|
|||
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
|
||||
|
||||
// Use 1/8th of the available memory for this memory cache.
|
||||
final int cacheSize = 1024 * 1024 * memClass / 8;
|
||||
private LruCache<Long, Bitmap> imageCache;
|
||||
final int coverCacheSize = 1024 * 1024 * memClass / 10;
|
||||
final int thumbnailCacheSize = 1024 * 1024 * memClass / 6;
|
||||
|
||||
private LruCache<Long, Bitmap> coverCache;
|
||||
private LruCache<Long, Bitmap> thumbnailCache;
|
||||
|
||||
private FeedImageLoader() {
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "Creating cache with size " + cacheSize);
|
||||
imageCache = new LruCache<Long, Bitmap>(cacheSize) {
|
||||
coverCache = new LruCache<Long, Bitmap>(coverCacheSize) {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected int sizeOf(Long key, Bitmap value) {
|
||||
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12)
|
||||
return value.getByteCount();
|
||||
else
|
||||
return (value.getRowBytes() * value.getHeight());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
thumbnailCache = new LruCache<Long, Bitmap>(thumbnailCacheSize) {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
|
@ -60,18 +79,19 @@ public class FeedImageLoader {
|
|||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public void loadBitmap(FeedImage image, ImageView target) {
|
||||
public void loadCoverBitmap(FeedImage image, ImageView target) {
|
||||
if (image != null) {
|
||||
Bitmap bitmap = getBitmapFromCache(image.getId());
|
||||
Bitmap bitmap = getBitmapFromCoverCache(image.getId());
|
||||
if (bitmap != null) {
|
||||
target.setImageBitmap(bitmap);
|
||||
} else {
|
||||
target.setImageResource(R.drawable.default_cover);
|
||||
BitmapWorkerTask worker = new BitmapWorkerTask(target);
|
||||
BitmapWorkerTask worker = new BitmapWorkerTask(target, image,
|
||||
LENGTH_BASE_COVER);
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, image);
|
||||
worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
worker.execute(image);
|
||||
worker.execute();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -79,42 +99,93 @@ public class FeedImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public void addBitmapToCache(long id, Bitmap bitmap) {
|
||||
imageCache.put(id, bitmap);
|
||||
@SuppressLint("NewApi")
|
||||
public void loadThumbnailBitmap(FeedImage image, ImageView target) {
|
||||
if (image != null) {
|
||||
Bitmap bitmap = getBitmapFromThumbnailCache(image.getId());
|
||||
if (bitmap != null) {
|
||||
target.setImageBitmap(bitmap);
|
||||
} else {
|
||||
target.setImageResource(R.drawable.default_cover);
|
||||
BitmapWorkerTask worker = new BitmapWorkerTask(target, image,
|
||||
LENGTH_BASE_THUMBNAIL);
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
worker.execute();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
target.setImageResource(R.drawable.default_cover);
|
||||
}
|
||||
}
|
||||
|
||||
public void wipeImageCache() {
|
||||
imageCache.evictAll();
|
||||
coverCache.evictAll();
|
||||
thumbnailCache.evictAll();
|
||||
}
|
||||
|
||||
public boolean isInCache(FeedImage image) {
|
||||
return imageCache.get(image.getId()) != null;
|
||||
public boolean isInThumbnailCache(FeedImage image) {
|
||||
return thumbnailCache.get(image.getId()) != null;
|
||||
}
|
||||
|
||||
public Bitmap getBitmapFromCache(long id) {
|
||||
return imageCache.get(id);
|
||||
public Bitmap getBitmapFromThumbnailCache(long id) {
|
||||
return thumbnailCache.get(id);
|
||||
}
|
||||
|
||||
class BitmapWorkerTask extends AsyncTask<FeedImage, Void, Void> {
|
||||
/** The preferred width and height of a bitmap. */
|
||||
private static final int LENGTH_BASE_VALUE = 200;
|
||||
public void addBitmapToThumbnailCache(long id, Bitmap bitmap) {
|
||||
thumbnailCache.put(id, bitmap);
|
||||
}
|
||||
|
||||
public boolean isInCoverCache(FeedImage image) {
|
||||
return coverCache.get(image.getId()) != null;
|
||||
}
|
||||
|
||||
public Bitmap getBitmapFromCoverCache(long id) {
|
||||
return coverCache.get(id);
|
||||
}
|
||||
|
||||
public void addBitmapToCoverCache(long id, Bitmap bitmap) {
|
||||
coverCache.put(id, bitmap);
|
||||
}
|
||||
|
||||
class BitmapWorkerTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private int PREFERRED_LENGTH;
|
||||
|
||||
private static final String TAG = "BitmapWorkerTask";
|
||||
private ImageView target;
|
||||
private Bitmap bitmap;
|
||||
private Bitmap decodedBitmap;
|
||||
|
||||
private int baseLength;
|
||||
|
||||
public BitmapWorkerTask(ImageView target) {
|
||||
private FeedImage image;
|
||||
|
||||
public BitmapWorkerTask(ImageView target, FeedImage image, int length) {
|
||||
super();
|
||||
this.target = target;
|
||||
this.PREFERRED_LENGTH = (int) (LENGTH_BASE_VALUE * PodcastApp.getLogicalDensity());
|
||||
this.image = image;
|
||||
this.baseLength = length;
|
||||
this.PREFERRED_LENGTH = (int) (length * PodcastApp
|
||||
.getLogicalDensity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
super.onPostExecute(result);
|
||||
target.setImageBitmap(bitmap);
|
||||
// check if imageview is still supposed to display this image
|
||||
if (target.getTag() == null || target.getTag() == image) {
|
||||
target.setImageBitmap(bitmap);
|
||||
} else {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Not displaying image");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
private int calculateSampleSize(int width, int height) {
|
||||
|
@ -139,50 +210,54 @@ public class FeedImageLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(FeedImage... params) {
|
||||
protected Void doInBackground(Void... params) {
|
||||
File f = null;
|
||||
if (params[0].getFile_url() != null) {
|
||||
f = new File(params[0].getFile_url());
|
||||
if (image.getFile_url() != null) {
|
||||
f = new File(image.getFile_url());
|
||||
}
|
||||
if (params[0].getFile_url() != null && f.exists()) {
|
||||
if (image.getFile_url() != null && f.exists()) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(params[0].getFile_url(), options);
|
||||
BitmapFactory.decodeFile(image.getFile_url(), options);
|
||||
int sampleSize = calculateSampleSize(options.outWidth,
|
||||
options.outHeight);
|
||||
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = sampleSize;
|
||||
decodedBitmap = BitmapFactory.decodeFile(
|
||||
params[0].getFile_url(), options);
|
||||
decodedBitmap = BitmapFactory.decodeFile(image.getFile_url(),
|
||||
options);
|
||||
if (decodedBitmap == null) {
|
||||
Log.i(TAG,
|
||||
"Bitmap could not be decoded in custom sample size. Trying default sample size (path was "
|
||||
+ params[0].getFile_url() + ")");
|
||||
decodedBitmap = BitmapFactory.decodeFile(params[0]
|
||||
+ image.getFile_url() + ")");
|
||||
decodedBitmap = BitmapFactory.decodeFile(image
|
||||
.getFile_url());
|
||||
}
|
||||
if (decodedBitmap != null) {
|
||||
bitmap = Bitmap.createScaledBitmap(decodedBitmap,
|
||||
PREFERRED_LENGTH, PREFERRED_LENGTH, false);
|
||||
|
||||
addBitmapToCache(params[0].getId(), bitmap);
|
||||
bitmap = Bitmap.createScaledBitmap(decodedBitmap,
|
||||
PREFERRED_LENGTH, PREFERRED_LENGTH, false);
|
||||
if (baseLength == LENGTH_BASE_COVER) {
|
||||
addBitmapToCoverCache(image.getId(), bitmap);
|
||||
} else if (baseLength == LENGTH_BASE_THUMBNAIL) {
|
||||
addBitmapToThumbnailCache(image.getId(), bitmap);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "Could not load bitmap. Using default image.");
|
||||
bitmap = BitmapFactory.decodeResource(target.getResources(),
|
||||
R.drawable.default_cover);
|
||||
bitmap = BitmapFactory.decodeResource(
|
||||
target.getResources(), R.drawable.default_cover);
|
||||
}
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "Finished loading bitmaps");
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Finished loading bitmaps");
|
||||
} else {
|
||||
Log.e(TAG,
|
||||
"FeedImage has no valid file url. Using default image");
|
||||
bitmap = BitmapFactory.decodeResource(target.getResources(),
|
||||
R.drawable.default_cover);
|
||||
if (params[0].getFile_url() != null
|
||||
if (image.getFile_url() != null
|
||||
&& !DownloadRequester.getInstance().isDownloadingFile(
|
||||
params[0])) {
|
||||
image)) {
|
||||
FeedManager.getInstance().notifyInvalidImageFile(
|
||||
PodcastApp.getInstance(), params[0]);
|
||||
PodcastApp.getInstance(), image);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -81,7 +81,7 @@ public class CoverFragment extends SherlockFragment {
|
|||
}
|
||||
|
||||
private void loadMediaInfo() {
|
||||
FeedImageLoader.getInstance().loadBitmap(
|
||||
FeedImageLoader.getInstance().loadCoverBitmap(
|
||||
media.getItem().getFeed().getImage(), imgvCover);
|
||||
txtvTitle.setText(media.getItem().getTitle());
|
||||
txtvFeed.setText(media.getItem().getFeed().getTitle());
|
||||
|
|
Loading…
Reference in New Issue