0

I'm loading images in gridviev asynchronusly.But my gridview displaying only a single image in the last cell of gridview.My adapter class and asynchronus class is given below, thanks.

Adapter class:

class OrderAdapter extends ArrayAdapter<String>
{   
    LayoutInflater inflater;

    String name3[];
    public OrderAdapter(Context context,int resource,LayoutInflater inflater,String name2[])
    {
        super(context, resource,R.id.img,name2);
        this.inflater=inflater;
        this.name3=name2;
    }
    public View getView(int position, View convertView, ViewGroup parent)
    {  
        View row=inflater.inflate(R.layout.row,parent,false);
      final  ImageView img=(ImageView)row.findViewById(R.id.img);
        String imgurl=name3[position];
        Log.e("urlchandan",name3[position]);
        AsyncImageLoaderv asyncImageLoaderv=new AsyncImageLoaderv();
        Bitmap cachedImage = asyncImageLoaderv.loadDrawable(imgurl, new AsyncImageLoaderv.ImageCallback() 
            {
            public void imageLoaded(Bitmap imageDrawable, String imageUrl) {
            img.setImageBitmap(imageDrawable);

            }
            });
        img.setImageBitmap(cachedImage);     

        return row;
    }

}

Asynchronous class

public class AsyncImageLoaderv {
    private HashMap<String, SoftReference<Bitmap>> imageCache;

    public AsyncImageLoaderv() {
        imageCache = new HashMap<String, SoftReference<Bitmap>>();
    }

    public Bitmap loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
        if (imageCache.containsKey(imageUrl)) {
            SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
            Bitmap drawable = softReference.get();
            if (drawable != null) {
                return drawable;
            }
        }
        final Handler handler = new Handler() {
            @Override
                public void handleMessage(Message message) {
                    imageCallback.imageLoaded((Bitmap) message.obj, imageUrl);
                }
        };
        new Thread() {
            @Override
                public void run() {
                    try{
                        Log.d("ur",imageUrl);
                        Bitmap drawable = loadImageFromUrl(imageUrl);
                        imageCache.put(imageUrl, new SoftReference<Bitmap>(drawable));
                        Message message = handler.obtainMessage(0, drawable);
                        handler.sendMessage(message);
                    }catch(Exception e){Log.e("thread stellent",e.toString());}
                }
        }.start();
        return null;
    }


    public static Bitmap loadImageFromUrl(String url) {
            InputStream inputStream;Bitmap b;
            try {
                    inputStream = (InputStream) new URL(url).getContent();
                    BitmapFactory.Options bpo=  new BitmapFactory.Options();
                    bpo.inSampleSize=2;
                   b=BitmapFactory.decodeStream(new PatchInputStream(inputStream), null,bpo );
                    return  b;
            } catch (IOException e) {
                    throw new RuntimeException(e);
                }
//return null;
    }

    public interface ImageCallback {
        public void imageLoaded(Bitmap imageBitmap, String imageUrl);
    }
}
Pratik
  • 30,639
  • 18
  • 84
  • 159
kehnar
  • 1,387
  • 2
  • 12
  • 25

2 Answers2

1

You can't do it the way you're trying. You need to have your asynchronous loader store the resulting image in some data structure your adapter can access by position (e.g. a list, a hashmap, whatever). Your getView() should then simply pull the image from the correct position. Your asynchronous loader will populate the data structure and perform a notifyDataSetChanged() to have the list redraw itself with the newly loaded image.

Brian Dupuis
  • 8,136
  • 3
  • 25
  • 29
  • i ma using private HashMap> imageCache to store the image.view is called for every element and displaying all url in logcat Log.e("urlchandan",name3[position]); but it calling asyncImageLoaderv.loadDrawable() method only once or thrice . – kehnar May 12 '11 at 15:29
  • 1
    Your private HashMap needs to be accessible from the adapter, and it either sets the image in the view to the drawable if it's loaded or maybe it kicks off an async load if it's not loaded and not currently loading. You cannot have the code architected the way you currently have it with a callback that sets the bitmap. – Brian Dupuis May 12 '11 at 16:09
  • 1
    See http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012 for an example of the kind of methodology. – Brian Dupuis May 12 '11 at 16:10
0

I got the solution by making the ImageView img in adatper inflater as final because it avoids the images to display at a single cell in gridview . And my images was of big size and got the error decoder return false and this error is solved by taking another class

--

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class PatchInputStream extends FilterInputStream {
      public PatchInputStream(InputStream in) {
        super(in);
      }
      public long skip(long n) throws IOException {
        long m = 0L;
        while (m < n) {
          long _m = in.skip(n-m);
          if (_m == 0L) break;
          m += _m;
        }
        return m;
      }
    }

this class is used in AsyncImageLoaderv given above .

  b=BitmapFactory.decodeStream(new PatchInputStream(inputStream), null,bpo );
Pratik
  • 30,639
  • 18
  • 84
  • 159
kehnar
  • 1,387
  • 2
  • 12
  • 25