I am using lazy loading (fedorvlasov/lazylist) approach to download the image from the server but my problem is that as soon as i got the image from the server i want to save that in database but some of the images only save in the database.Please let me know the proper approach for this. if i implemented the queue does the problem solve.
public class ImageLoader {
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
public ImageLoader(Context context){
// fileCache=new FileCache(context);
executorService=Executors.newFixedThreadPool(0);
}
// final int stub_id=R.drawable.stub;
public void DisplayImage(String url, ImageView imageView)
{
imageViews.put(imageView, url);
Bitmap bitmap=null;//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);*/
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpGet mHttpGet = new HttpGet(url);
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
// if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
HttpEntity entity = mHttpResponse.getEntity();
if ( entity != null)
{
// String String=EntityUtils.toByteArray(entity).toString();
// String=convertResizedImage(String);
InputStream inputStream = null;
inputStream = entity.getContent();
// byte[] imgarrbyte = new byte[inputStream.available()];
//inputStream.read(imgarrbyte);
bitmap = BitmapFactory.decodeStream(inputStream);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, bos);
String cardimage = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
byte[] imgarrbyte = null;
try {
if (cardimage!= null) {
// Utils.writetoFile(, String.valueOf(position));
byte[] tempByArr = cardimage.getBytes();
imgarrbyte = Base64.decode(tempByArr,Base64.DEFAULT);
}
if (imgarrbyte != null && imgarrbyte.length > 0) {
bitmap = BitmapFactory.decodeByteArray(imgarrbyte, 0,
imgarrbyte.length);
}
}catch(OutOfMemoryError oome)
{
oome.printStackTrace();
}
}
}
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}
public String convertResizedImage(String imagedata) {
try {
// Step 1 : Image decoded
byte[] imageAsBytes = new byte[imagedata.length()];
imageAsBytes = Base64.decode(imagedata.getBytes("UTF8"),
Base64.DEFAULT);
BitmapFactory.Options opts = new BitmapFactory.Options();
int IMAGE_MAX_SIZE = 240, scale = 1;
if (opts.outHeight > IMAGE_MAX_SIZE
|| opts.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(2, (int) Math.round(Math
.log(IMAGE_MAX_SIZE
/ (double) Math.max(opts.outHeight,
opts.outWidth))
/ Math.log(0.5)));
}
// Step 2 : Compress the BITMAP
opts.inSampleSize = scale;
opts.inPurgeable = true;
opts.inPreferredConfig = Bitmap.Config.ARGB_4444;
// Decode with inSampleSize
opts.inJustDecodeBounds = false;
opts.inDither = false;
opts.inScaled = false;
// STEP 3 :
Bitmap bitMapimage = BitmapFactory.decodeByteArray(imageAsBytes, 0,
imageAsBytes.length, opts);
String tempstr = new String();
if (bitMapimage != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitMapimage.compress(CompressFormat.JPEG, 100, bos);
tempstr = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
}
return tempstr;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
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;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//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;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
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;
}
}
public void getImageSize(byte[] imgarrbyte, String fileName) {
File file = new File("/mnt/sdcard/", fileName);
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(imgarrbyte);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad){
this.photoToLoad=photoToLoad;
}
@Override
public void run() {
if(imageViewReused(photoToLoad))
return;
Bitmap bmp=getBitmap(photoToLoad.url);
if(imageViewReused(photoToLoad))
return;
addBitmapTodb(photoToLoad.url,bmp); //saving in database works sometimes.
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
Activity a=(Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
private void addBitmapTodb(String url, Bitmap bitmap) {
if (bitmap != null) {
Log.i("Bitmap", "addBitmapTodb==========");
Dao updateimage=new Dao();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, bos);
String cardimage = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
updateimage.updateimageindb(url,cardimage);
}
}
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);
}
}
}
thanks for reply again :) yes i m currently doing the same if you check function addBitmapTodb in above code.problem is here that i have used cursoradapater and calling imageloader from getview function by passing the imageurl,I have observed some isssue as like 1.if i do scrolling on listview,the same image url request is sent to imageloader for downloading the image 2.some of the images only saved in the database(maybe becouse of synchronization issue),I want to avoid such issue so i need some help on this.