Downloading Image in android using asynctask for RecyclerView - java

This my following AsyncTask class code for downloading image for RecyclerView.
public class MyDownloadImageAsyncTask extends AsyncTask<String, Void,Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public MyDownloadImageAsyncTask(ImageView imv) {
imageViewReference = new WeakReference<ImageView>(imv);
}
#Override
protected Bitmap doInBackground(String... urls) {
Bitmap bitmap = null;
for (String url : urls) {
bitmap = MyUtility.downloadImage(url);
/*if (bitmap != null) {
mImgMemoryCache.put(url, bitmap);
}*/
}
return bitmap;
}
protected void onPostExecute(Bitmap bitmap){
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
I call the AsyncTask in my Adapter this way:
MyDownloadImageAsyncTask task = new MyDownloadImageAsyncTask(holder.vIcon);
task.execute(new String[] {(String)movie.get("image")}););
The app is crashing every time I run it. The URL for downloading the image is in a ArrayList.
I guess the mistake I'm doing this in calling the AsyncTask but I couldn't figure out the solution.

Change this
public MyDownloadImageAsyncTask(ImageView imv) {
imageViewReference = new WeakReference(imv);
}
to this
public MyDownloadImageAsyncTask(ImageView imv) {
imageViewReference = new WeakReference<ImageView>(imv);
}
Here is the code that i use and it works perfect
class LoadImage extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public LoadImage(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... params) {
try {
return downloadBitmap(params[0]);
} catch (Exception e) {
// log error
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.ic_launcher);
imageView.setImageDrawable(placeholder);
}
}
}
}
private Bitmap downloadBitmap(String url) {
HttpURLConnection urlConnection = null;
try {
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
urlConnection.disconnect();
Log.w("ImageDownloader", "Error downloading image from " + url);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
}
And here is how i call it from my ADAPTER
new LoadImage(holder.itemImage).execute(IMAGE_URL);
seperately for every URL.
Try this if it helps you out.

Related

How to get image from url and cache it

I'm trying to get image from a url and updating it to an Image view. But the images are not being cached and reload when I scroll down then up
I'm using the following AsynkTask for updating images to ImageView
public class GetImageTask extends AsyncTask<Void, Void, Bitmap> {
private String url;
private ImageView imageView = null;
private CircleImageView circleImageView = null;
public GetImageTask(String url, CircleImageView circleImageView) {
this.url = url;
this.circleImageView = circleImageView;
}
public GetImageTask(String url, ImageView imageView) {
this.url = url;
this.imageView = imageView;
}
#Override
protected Bitmap doInBackground(Void... voids) {
try {
URL urlConnection = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConnection.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(inputStream);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if(imageView != null)
imageView.setImageBitmap(result);
if (circleImageView != null)
circleImageView.setImageBitmap(result);
}
}
But this doesn't cache the images please suggest an edit to cache the images

Icon size in Navigation Drawer

I have a navigation drawer in my app. I am making an HTTP request to load in friends and group names along with the pics. I want my pics to resize so they can adjust in. This is what i have
This is what i want
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
int k=0;
for(String n : friends){
String words[] = n.split(":");
menu.findItem(R.id.friends).getSubMenu().add(R.id.friends, Integer.parseInt(words[1]),k,words[0]);
MenuItem myMenuItem = menu.findItem(R.id.friends).getSubMenu().findItem(Integer.parseInt(words[1]));
DownloadImageTask dn = new DownloadImageTask(myMenuItem);
dn.execute(AppConfig.IMAGESURL + words[2]);
}
}
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<MenuItem> menuItemReference;
public DownloadImageTask(MenuItem menuItem) {
menuItemReference = new WeakReference<>(menuItem);
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (menuItemReference != null) {
MenuItem menuitem = menuItemReference.get();
if (menuitem != null) {
if (bitmap != null) {
Drawable r = new BitmapDrawable(getResources(),bitmap);
menuitem.setIcon(r);
} else {
// Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.placeholder);
// imageView.setImageDrawable(placeholder);
}
}
}
}
}

Using BitMaps to get images from Instagram API

I have build an app. I use bitmaps to get images from Instagram API and stora them in a GridView.
But I've a problem, when I use bitmaps and memory cache.
My code is:
public void DisplayImage(String urrl, ImageView imageView) {
String url = urrl.replaceAll(" ", "%20");
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
The variable bitmap returns null, from method memoryCache.get(url):
public Bitmap get(String id){
try{
if(!cache.containsKey(id)) {
return null; }else {
return cache.get(id); }
}catch(NullPointerException ex){
ex.printStackTrace();
return null;
}
}
I tried some solutions, but with no success.
I saw other solutions for similar problems, but neither can solve mine.
I'm new to bitmaps, and this kind of stuff.
EDIT
public class MemoryCache {
private static final String TAG = "MemoryCache";
private Map<String, Bitmap> cache= Collections.synchronizedMap(
new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
private long size=0;//current allocated size
private long limit=1000000;//max memory in bytes
public MemoryCache(){
//use 25% of available heap size
setLimit(Runtime.getRuntime().maxMemory()/4);
}
public void setLimit(long new_limit){
limit=new_limit;
Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
}
public Bitmap get(String id){
try{
if(!cache.containsKey(id)) {
return null; }else {
//NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78
return cache.get(id); }
}catch(NullPointerException ex){
ex.printStackTrace();
return null;
}
}
public void put(String id, Bitmap bitmap){
try{
if(cache.containsKey(id))
size-=getSizeInBytes(cache.get(id));
cache.put(id, bitmap);
size+=getSizeInBytes(bitmap);
checkSize();
}catch(Throwable th){
th.printStackTrace();
}
}
private void checkSize() {
Log.i(TAG, "cache size="+size+" length="+cache.size());
if(size>limit){
Iterator<Map.Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated
while(iter.hasNext()){
Map.Entry<String, Bitmap> entry=iter.next();
size-=getSizeInBytes(entry.getValue());
iter.remove();
if(size<=limit)
break;
}
Log.i(TAG, "Clean cache. New size "+cache.size());
}
}
public void clear() {
try{
//NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78
cache.clear();
size=0;
}catch(NullPointerException ex){
ex.printStackTrace();
}
}
long getSizeInBytes(Bitmap bitmap) {
if(bitmap==null)
return 0;
return bitmap.getRowBytes() * bitmap.getHeight();
}
}
ImageLoader:
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
Handler handler = new Handler();// handler to display images in UI thread
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
}
final int stub_id = R.drawable.crayon;
public void DisplayImage(String urrl, ImageView imageView) {
String url = urrl.replaceAll(" ", "%20");
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url) {
File f = fileCache.getFile(url);
// from SD cache
Bitmap b = decodeFile(f);
if (b != null)
return b;
// from web
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
FileInputStream stream2 = new FileInputStream(f);
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Task for the queue
private class PhotoToLoad {
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
#Override
public void run() {
try {
if (imageViewReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
if (bitmap != null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
SOLUTION
In class MyGridView, i used Glide like Shmuel send on link!
View view = inflater.inflate(R.layout.medialist_inflate, null);
imgView = (ImageView) view.findViewById(R.id.ivImage);
Glide.with(context).load(imageThumbList.get(position)).into(imgView);
return view;
For loading images from a web url the best practice approach is the use the Glide image loading library.
https://github.com/bumptech/glide
It is an open source image loading library that is recommend and supported by Google.
The api looks like this -
Glide
.with(context)
.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.crossFade()
.into(myImageView);
See how easy that is :D
It automatically handles caching the images (both in memory and to disk).

SkImageDecoder::Factory returned null and URL is correct

I'm trying to put an Image from a URL in a ImageView, but I keep getting the "SkImageDecoder::Factory returned null" error.
Here's my code:
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String myUrl= urls[0];
Bitmap myBmp= null;
try {
InputStream in = new URL(urldisplay).openStream();
myBmp= BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return myBmp;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
EDIT: logcat when the app crashes after getting the first image
logcat
public class customAdapter extends ArrayAdapter<String> {
private final Context context;
private final ArrayList<String> values;
static class ViewHolder {
private TextView textViewName;
private TextView textViewType;
private ImageView imageView;
}
public customAdapter(Context context, ArrayList<String> values) {
super(context, R.layout.list_member, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder = null;
if (convertView == null) {
mViewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_member, parent, false);
mViewHolder.textViewName = (TextView) convertView.findViewById(R.id.name);
mViewHolder.textViewType = (TextView) convertView.findViewById(R.id.type);
mViewHolder.imageView = (ImageView) convertView.findViewById(R.id.image);
convertView.setTag(mViewHolder);
}
else {
mViewHolder = (ViewHolder) convertView.getTag();
}
String s = values.get(position);
StringTokenizer st = new StringTokenizer(s, "*");
String name = st.nextToken();
String url_photo = st.nextToken();
String type = st.nextToken();
if (type.equals("CHILD")) {
String count_dev = st.nextToken();
mViewHolder.textViewType.setText(count_dev);
}
else {
mViewHolder.textViewType.setText(type);
}
mViewHolder.textViewName.setText(name);
new DownloadImageTask(mViewHolder.imageView).execute(url_photo);
return convertView;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
// TODO Auto-generated method stub
String urlStr = urls[0];
Bitmap img = null;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(urlStr);
HttpResponse response;
try {
response = (HttpResponse)client.execute(request);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
InputStream inputStream = bufferedEntity.getContent();
img = BitmapFactory.decodeStream(inputStream);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
As requested, this is the full code for this class
Try to add this code in your background method:
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
String urlStr = params[0];
Bitmap img = null;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(urlStr);
HttpResponse response;
try {
response = (HttpResponse)client.execute(request);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
InputStream inputStream = bufferedEntity.getContent();
img = BitmapFactory.decodeStream(inputStream);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return img;
}

How to Store Image in SDCard using Service?

I am getting the Image URL and set that URL in GridView.it shows me Successfully in Gridview.But I also want to Store That Images in SDCard Using Service.How to do That.Please Someone Help me for my this Issue.Thank You.
public class MainActivity extends Activity {
ListView list;
GridView gv;
String TAG = "GRIDVIEW";
LazyAdapter adapter;
Bitmap bitmap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyService.class));
new loading().execute();
// gv = (GridView) findViewById(R.id.grid_view);
// startService(new Intent(MainActivity.this, MyService.class));
// gv = (GridView) findViewById(R.id.grid_view);
// gv.setAdapter(new LazyAdapter(MainActivity.this, mStrings));
// gv.setHorizontalSpacing(10);
// gv.setVerticalSpacing(40);
// gv.setGravity(200);
}
ProgressDialog mprogress;
private class loading extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
mprogress = new ProgressDialog(MainActivity.this);
mprogress.setMessage("Loading...");
mprogress.show();
super.onPreExecute();
}
protected String doInBackground(String... params) {
// startService(new Intent(MainActivity.this, MyService.class));
return null;
}
protected void onPostExecute(String result) {
getGirdview();
mprogress.dismiss();
super.onPostExecute(result);
}
private void getGirdview() {
gv = (GridView) findViewById(R.id.grid_view);
gv.setAdapter(new LazyAdapter(MainActivity.this, mStrings));
gv.setHorizontalSpacing(10);
gv.setVerticalSpacing(40);
}
}
public String[] mStrings = {
"http://a1.twimg.com/profile_images/97470808/icon_normal.png",
"http://a3.twimg.com/profile_images/511790713/AG.png",
};
}
public class MyService extends Service {
String TAG = "GRIDVIEW";
Bitmap bitmap;
MainActivity mclass = new MainActivity();
public void onStart(Intent intent, int startId) {
for (int i = 0; i < mclass.mStrings.length; i++) {
String str = mclass.mStrings[i];
bitmap = DownloadImage(str);
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
// R.drawable.ic_launcher);
// File sd = Environment.getExternalStorageDirectory();
File storagePath = new File(
Environment.getExternalStorageDirectory(), "Wallpaper");
storagePath.mkdirs();
String fileName = "test" + i + ".png";
File dest = new File(storagePath, fileName);
try {
FileOutputStream out;
out = new FileOutputStream(dest);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
super.onStart(intent, startId);
}
public int onStartCommand(Intent intent, int flags, int startId) {
// for (int i = 0; i < mStrings.length; i++) {
//
// String str = mStrings[i];
// bitmap = DownloadImage(str);
// // Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
// // R.drawable.ic_launcher);
// // File sd = Environment.getExternalStorageDirectory();
// File storagePath = new File(
// Environment.getExternalStorageDirectory(), "Wallpaper");
// storagePath.mkdirs();
//
// String fileName = "test" + i + ".png";
// File dest = new File(storagePath, fileName);
// try {
// FileOutputStream out;
// out = new FileOutputStream(dest);
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
// out.flush();
// out.close();
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
// public void onStart(Intent intent, int startId) {
//
// for (int i = 0; i < mStrings.length; i++) {
//
// String str = mStrings[i];
// bitmap = DownloadImage(str);
// // Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
// // R.drawable.ic_launcher);
// // File sd = Environment.getExternalStorageDirectory();
// File storagePath = new File(
// Environment.getExternalStorageDirectory(), "Wallpaper");
// storagePath.mkdirs();
//
// String fileName = "test" + i + ".png";
// File dest = new File(storagePath, fileName);
// try {
// FileOutputStream out;
// out = new FileOutputStream(dest);
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
// out.flush();
// out.close();
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// super.onStart(intent, startId);
// }
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Toast.makeText(MyService.this, "Image is Downloaded",
Toast.LENGTH_SHORT).show();
return bitmap;
}
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
}
final int stub_id = R.drawable.ic_launcher;
public void DisplayImage(String url, ImageView imageView) {
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url) {
File f = fileCache.getFile(url);
// from SD cache
Bitmap b = decodeFile(f);
if (b != null)
return b;
// from web
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
FileInputStream stream2 = new FileInputStream(f);
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// Task for the queue
private class PhotoToLoad {
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
#Override
public void run() {
try {
if (imageViewReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
Activity a = (Activity) photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
if (bitmap != null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
public class LazyAdapter extends BaseAdapter {
private Context mContext;
String TAG = "GridView";
private Activity activity;
private String[] data;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
Bitmap bitmap;
public LazyAdapter(Activity a, String[] d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return data;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, null);
}
// TextView txt_name = (TextView) convertView.findViewById(R.id.text);
// txt_name.setText("item" + position);
ImageView image = (ImageView) convertView.findViewById(R.id.image);
// image.setTag(data[position]);
imageLoader.DisplayImage(data[position], image);
return convertView;
}
}
Environment.getExternalStorage() will return the sd card location. Once you get the location, you can create directories as needed. Looks like you are doing it....so what is the issue that you are running into?
Also, use IntentService rather than a service......it takes care of most of the plumbing work for you.

Categories

Resources