/***************************************************************************
* Copyright 2005-2009 Last.fm Ltd. *
* Portions contributed by Casey Link, Lukasz Wisniewski, *
* Mike Jennings, and Michael Novak Jr. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
package fm.last.android.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
/**
* Class responsible for downloading images asynchronously in a separate threads
*
* @author Lukasz Wisniewski
*/
public class ImageDownloader {
private static final String TASK_TAG_DEFAULT = "default";
protected static final String TAG = "ImageDownloader";
ImageDownloaderListener mListener;
ImageCache mImageCache;
/**
* Handle to ongoing tasks
*/
private Hashtable<String, AsyncTaskEx<String, Integer, Object>> mTasks;
/**
* Default constructor
*
* @param imageCache
*/
public ImageDownloader(ImageCache imageCache) {
if (imageCache == null) {
imageCache = new ImageCache();
}
this.mImageCache = imageCache;
mTasks = new Hashtable<String, AsyncTaskEx<String, Integer, Object>>();
}
public void setListener(ImageDownloaderListener l) {
this.mListener = l;
}
/**
* Requests image download
*
* @param url
*/
public void getImage(String url) {
AsyncTaskEx<String, Integer, Object> AsyncTaskEx = new AsyncTaskEx<String, Integer, Object>() {
URL imageUrl;
@Override
public void onPostExecute(Object result) {
if (mListener != null && imageUrl != null) {
mListener.imageDownloaded(imageUrl.toString());
}
}
@Override
public void onPreExecute() {
}
@Override
public Object doInBackground(String... params) {
String url = params[0];
if (url == null || url.trim().length() == 0)
return null;
// check if we have already downloaded an url
if (!mImageCache.containsKey(url)) {
InputStream stream = null;
try {
imageUrl = new URL(url);
try {
stream = imageUrl.openStream();
final Bitmap bmp = BitmapFactory.decodeStream(stream);
try {
mImageCache.put(url, bmp);
} catch (NullPointerException e) {
Log.e(TAG, "Failed to cache " + url);
}
} catch (OutOfMemoryError e) {
Log.w(TAG, "Couldn't load bitmap from url: " + url, e);
} catch (Exception e) {
Log.w(TAG, "Couldn't load bitmap from url: " + url, e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
}
}
} catch (MalformedURLException e) {
Log.w(TAG, "Wrong url: " + url, e);
}
} // END: check if we have already downloaded an url
return null;
}
};
mTasks.put(url, AsyncTaskEx);
AsyncTaskEx.execute(url);
}
/**
* Returns AsyncTaskEx instance initialized with
* getImages(ArrayList<String> urls) request
*
* @return
*/
public final AsyncTaskEx<String, Integer, Object> getAsyncTaskEx() {
if (mTasks.containsKey(TASK_TAG_DEFAULT)) {
return mTasks.get(TASK_TAG_DEFAULT);
}
return null;
}
/**
* Returns AsyncTaskEx instance initialized with
* getImages(ArrayList<String> urls, String tag) request
*
* @return
*/
public final AsyncTaskEx<String, Integer, Object> getAsyncTaskEx(String tag) {
if (mTasks.containsKey(tag)) {
return mTasks.get(tag);
}
return null;
}
}