gridview中的异步图像加载

时间:2011-05-12 14:52:15

标签: android asynchronous image-loading

我在gridviev asynchronusly中加载图片。但是我的gridview只在gridview的最后一个单元格中显示了一个图像。我的适配器类和asynchronus类在下面给出,谢谢。

适配器类:

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

}

异步类

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

2 个答案:

答案 0 :(得分:1)

你无法按照自己的方式去做。您需要让异步加载器将结果图像存储在适配器可以按位置访问的某些数据结构中(例如列表,散列图等)。然后,您的getView()应该只是从正确的位置拉出图像。您的异步加载器将填充数据结构并执行notifyDataSetChanged()以使列表重新绘制新加载的图像。

答案 1 :(得分:0)

我通过将adatper inflater中的ImageView img作为最终版本来获得解决方案,因为它避免了 要在gridview中的单个单元格中显示的图像。而且我的图像尺寸很大,错误解码器返回false,这个错误通过另一个类来解决

-

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

此类用于上面给出的AsyncImageLoaderv。

  b=BitmapFactory.decodeStream(new PatchInputStream(inputStream), null,bpo );