Moved BitmapDecodeWorker into separate class

This commit is contained in:
daniel oeh 2012-08-03 13:04:16 +02:00
parent 76a35f11a0
commit fde6a05f18
2 changed files with 176 additions and 127 deletions

View File

@ -0,0 +1,140 @@
package de.danoeh.antennapod.asynctask;
import java.io.File;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
public abstract class BitmapDecodeWorkerTask extends
AsyncTask<Void, Void, Void> {
private int PREFERRED_LENGTH;
public static final int LENGTH_BASE_COVER = 200;
public static final int LENGTH_BASE_THUMBNAIL = 100;
private static final String TAG = "BitmapDecodeWorkerTask";
private ImageView target;
private Bitmap bitmap;
private Bitmap decodedBitmap;
protected int baseLength;
private String fileUrl;
public BitmapDecodeWorkerTask(ImageView target, String fileUrl, int length) {
super();
this.target = target;
this.fileUrl = fileUrl;
this.baseLength = length;
this.PREFERRED_LENGTH = (int) (length * PodcastApp.getLogicalDensity());
}
/**
* Should return true if tag of the imageview is still the same it was
* before the bitmap was decoded
*/
abstract protected boolean tagsMatching(ImageView target);
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// check if imageview is still supposed to display this image
if (tagsMatching(target)) {
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) {
int max = Math.max(width, height);
if (max < PREFERRED_LENGTH) {
return 1;
} else {
// find first sample size where max / sampleSize <
// PREFERRED_LENGTH
for (int sampleSize = 1, power = 0;; power++, sampleSize = (int) Math
.pow(2, power)) {
int newLength = max / sampleSize;
if (newLength <= PREFERRED_LENGTH) {
if (newLength > 0) {
return sampleSize;
} else {
return sampleSize - 1;
}
}
}
}
}
@Override
protected Void doInBackground(Void... params) {
File f = null;
if (fileUrl != null) {
f = new File(fileUrl);
}
if (fileUrl != null && f.exists()) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileUrl, options);
int sampleSize = calculateSampleSize(options.outWidth,
options.outHeight);
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
decodedBitmap = BitmapFactory.decodeFile(fileUrl,
options);
if (decodedBitmap == null) {
Log.i(TAG,
"Bitmap could not be decoded in custom sample size. Trying default sample size (path was "
+ fileUrl + ")");
decodedBitmap = BitmapFactory.decodeFile(fileUrl);
}
if (decodedBitmap != null) {
bitmap = Bitmap.createScaledBitmap(decodedBitmap,
PREFERRED_LENGTH, PREFERRED_LENGTH, false);
storeBitmapInCache(bitmap);
} else {
Log.w(TAG, "Could not load bitmap. Using default image.");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
}
if (AppConfig.DEBUG)
Log.d(TAG, "Finished loading bitmaps");
} else {
onInvalidFileUrl();
}
return null;
}
protected void onInvalidFileUrl() {
Log.e(TAG, "FeedImage has no valid file url. Using default image");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
}
protected abstract void storeBitmapInCache(Bitmap bitmap);
@SuppressLint("NewApi")
public void executeAsync() {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
execute();
}
}
}

View File

@ -1,22 +1,16 @@
package de.danoeh.antennapod.asynctask; package de.danoeh.antennapod.asynctask;
import java.io.File;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.feed.FeedImage;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.R;
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.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
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 de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.FeedImage;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.storage.DownloadRequester;
/** Caches and loads FeedImage bitmaps in the background */ /** Caches and loads FeedImage bitmaps in the background */
public class FeedImageLoader { public class FeedImageLoader {
@ -78,7 +72,6 @@ public class FeedImageLoader {
return singleton; return singleton;
} }
@SuppressLint("NewApi")
public void loadCoverBitmap(FeedImage image, ImageView target) { public void loadCoverBitmap(FeedImage image, ImageView target) {
if (image != null) { if (image != null) {
Bitmap bitmap = getBitmapFromCoverCache(image.getId()); Bitmap bitmap = getBitmapFromCoverCache(image.getId());
@ -86,20 +79,15 @@ public class FeedImageLoader {
target.setImageBitmap(bitmap); target.setImageBitmap(bitmap);
} else { } else {
target.setImageResource(R.drawable.default_cover); target.setImageResource(R.drawable.default_cover);
BitmapWorkerTask worker = new BitmapWorkerTask(target, image, FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
LENGTH_BASE_COVER); target, image, LENGTH_BASE_COVER);
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { worker.executeAsync();
worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
worker.execute();
}
} }
} else { } else {
target.setImageResource(R.drawable.default_cover); target.setImageResource(R.drawable.default_cover);
} }
} }
@SuppressLint("NewApi")
public void loadThumbnailBitmap(FeedImage image, ImageView target) { public void loadThumbnailBitmap(FeedImage image, ImageView target) {
if (image != null) { if (image != null) {
Bitmap bitmap = getBitmapFromThumbnailCache(image.getId()); Bitmap bitmap = getBitmapFromThumbnailCache(image.getId());
@ -107,13 +95,9 @@ public class FeedImageLoader {
target.setImageBitmap(bitmap); target.setImageBitmap(bitmap);
} else { } else {
target.setImageResource(R.drawable.default_cover); target.setImageResource(R.drawable.default_cover);
BitmapWorkerTask worker = new BitmapWorkerTask(target, image, FeedImageDecodeWorkerTask worker = new FeedImageDecodeWorkerTask(
LENGTH_BASE_THUMBNAIL); target, image, LENGTH_BASE_THUMBNAIL);
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { worker.executeAsync();
worker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
worker.execute();
}
} }
} else { } else {
target.setImageResource(R.drawable.default_cover); target.setImageResource(R.drawable.default_cover);
@ -149,119 +133,44 @@ public class FeedImageLoader {
coverCache.put(id, bitmap); coverCache.put(id, bitmap);
} }
class BitmapWorkerTask extends AsyncTask<Void, Void, Void> { class FeedImageDecodeWorkerTask extends BitmapDecodeWorkerTask {
private int PREFERRED_LENGTH; private static final String TAG = "FeedImageDecodeWorkerTask";
private static final String TAG = "BitmapWorkerTask"; protected FeedImage image;
private ImageView target;
private Bitmap bitmap;
private Bitmap decodedBitmap;
private int baseLength; public FeedImageDecodeWorkerTask(ImageView target, FeedImage image,
int length) {
private FeedImage image; super(target, image.getFile_url(), length);
public BitmapWorkerTask(ImageView target, FeedImage image, int length) {
super();
this.target = target;
this.image = image; this.image = image;
this.baseLength = length;
this.PREFERRED_LENGTH = (int) (length * PodcastApp
.getLogicalDensity());
} }
@Override @Override
protected void onPostExecute(Void result) { protected boolean tagsMatching(ImageView target) {
super.onPostExecute(result); return target.getTag() == null || target.getTag() == image;
// 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 @Override
protected void onPreExecute() { protected void storeBitmapInCache(Bitmap bitmap) {
super.onPreExecute();
}
private int calculateSampleSize(int width, int height) {
int max = Math.max(width, height);
if (max < PREFERRED_LENGTH) {
return 1;
} else {
// find first sample size where max / sampleSize <
// PREFERRED_LENGTH
for (int sampleSize = 1, power = 0;; power++, sampleSize = (int) Math
.pow(2, power)) {
int newLength = max / sampleSize;
if (newLength <= PREFERRED_LENGTH) {
if (newLength > 0) {
return sampleSize;
} else {
return sampleSize - 1;
}
}
}
}
}
@Override
protected Void doInBackground(Void... params) {
File f = null;
if (image.getFile_url() != null) {
f = new File(image.getFile_url());
}
if (image.getFile_url() != null && f.exists()) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image.getFile_url(), options);
int sampleSize = calculateSampleSize(options.outWidth,
options.outHeight);
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
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 "
+ image.getFile_url() + ")");
decodedBitmap = BitmapFactory.decodeFile(image
.getFile_url());
}
if (decodedBitmap != null) {
bitmap = Bitmap.createScaledBitmap(decodedBitmap,
PREFERRED_LENGTH, PREFERRED_LENGTH, false);
if (baseLength == LENGTH_BASE_COVER) { if (baseLength == LENGTH_BASE_COVER) {
addBitmapToCoverCache(image.getId(), bitmap); addBitmapToCoverCache(image.getId(), bitmap);
} else if (baseLength == LENGTH_BASE_THUMBNAIL) { } else if (baseLength == LENGTH_BASE_THUMBNAIL) {
addBitmapToThumbnailCache(image.getId(), bitmap); addBitmapToThumbnailCache(image.getId(), bitmap);
} }
} else {
Log.w(TAG, "Could not load bitmap. Using default image.");
bitmap = BitmapFactory.decodeResource(
target.getResources(), R.drawable.default_cover);
} }
if (AppConfig.DEBUG)
Log.d(TAG, "Finished loading bitmaps"); @Override
} else { protected void onInvalidFileUrl() {
Log.e(TAG, super.onInvalidFileUrl();
"FeedImage has no valid file url. Using default image");
bitmap = BitmapFactory.decodeResource(target.getResources(),
R.drawable.default_cover);
if (image.getFile_url() != null if (image.getFile_url() != null
&& !DownloadRequester.getInstance().isDownloadingFile( && !DownloadRequester.getInstance()
image)) { .isDownloadingFile(image)) {
FeedManager.getInstance().notifyInvalidImageFile( FeedManager.getInstance().notifyInvalidImageFile(
PodcastApp.getInstance(), image); PodcastApp.getInstance(), image);
} }
} }
return null;
}
} }
} }