0

我正在使用延迟加载(fedorvlasov/lazylist)方法从服务器下载图像,但我的问题是,一旦我从服务器获取图像,我想将其保存在数据库中,但有些图像只保存在数据库中.请让我知道正确的方法。如果我实现了队列,问题就解决了。

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);
        }
    }






}

感谢您再次回复:) 是的,如果您在上面的代码中检查函数 addBitmapTodb,我目前正在做同样的事情。问题在这里,我使用 cursoradapater 并通过传递 imageurl 从 getview 函数调用 imageloader,我观察到一些问题,如 1.if我在 listview 上滚动,相同的图像 url 请求被发送到 imageloader 以下载图像 2.一些图像只保存在数据库中(可能是因为同步问题),我想避免这样的问题,所以我需要一些帮助这个。

4

0 回答 0