0

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.

ChrisF
  • 131,190
  • 30
  • 250
  • 321
user853341
  • 149
  • 2
  • 12
  • You should not save image in to database, Have a Look [here](http://stackoverflow.com/a/9141116/996493) to my answer. – Lucifer May 16 '12 at 03:48
  • that is our requirement i have to do that,could you please suggest any other approach . – user853341 May 16 '12 at 03:57
  • yes, Just Store Images in to a SD Card folder and store the path of the Image in to Sqlite, this would be the faster in process – Lucifer May 16 '12 at 03:58
  • hi,thanks for your reply,it is ok if the process is a bit slow .i want to save the a whole image in database only as per the requirement.could you please tell me any other approach to do so. – user853341 May 16 '12 at 04:13
  • but when there will be a situation when you have more than 500 images, then it will slow down the retrieval and save process and it may surely create a situation of `Force Close` – Lucifer May 16 '12 at 04:15
  • there may not be the case as discussed.we are at most only 30images would be there – user853341 May 16 '12 at 04:50
  • then you can simply store image as byte array in the sqlite. – Lucifer May 16 '12 at 04:54
  • 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. – user853341 May 16 '12 at 04:57
  • you can check this ans : http://stackoverflow.com/questions/7516933/how-to-create-a-table-with-a-column-of-type-blob-in-a-dbadapter – Shoshi Mar 16 '13 at 11:29

0 Answers0