如何在listview中缓存imageview?

时间:2013-04-11 09:31:19

标签: android listview caching bitmap imageview

我和这个家伙有同样的问题 Listview shows wrong images

我看到了我必须缓存它的解决方案。但在我的缓存中,我不确定如何应用解决方案中给出的缓存。我一直收到错误。

我怀疑这是我遇到问题的部分:

holder.icon.setImageBitmap(bitmapList[position]);

            //loadImageBitmap(mObjects.get(position), position);

            //onBitmapLoaded(position, holder.mTask.myBitmap());

以下是代码。 Adapter.java     公共类适配器扩展BaseAdapter {

    private static final String TAG = "Adapter";
    private Activity mActivity;
    public ArrayList<Data> mObjects;

    static class ViewHolder {
        ImageView icon;
        TextView title;
        WebView newimage;
        DownloadImageTask mTask;
        public void setOnClickListener(OnItemClickListener onItemClickListener) {
            // TODO Auto-generated method stub

        }
    }



    private Bitmap[] bitmapList;
    private Bitmap bitmapPlaceholder;  

    private void initBitmapListWithPlaceholders(){ 
    // call this whenever the list size changes
    // you can also use a list or a map or whatever so you 
    // don't need to drop all the previously loaded bitmap whenever 
    // the list contents are modified
        int count = getCount();
        bitmapList = new Bitmap[count];
        for(int i=0;i<count;i++){
             bitmapList[i]=bitmapPlaceholder;
        }
    }

    private void onBitmapLoaded(int position, Bitmap bmp){
    // this is your callback when the load async is done
        bitmapList[position] = bmp;
    }

    public Adapter(Activity activity, ArrayList<Data> mObjects) {

        this.mActivity = (Activity) activity;
        this.mObjects = mObjects;


    }

    public void setObjects(ArrayList<Data> mObjects) {
        this.mObjects = mObjects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Data item = mObjects.get(position);
        View rowView = convertView;

        if (rowView == null) {
            LayoutInflater inflater = mActivity.getLayoutInflater();
            rowView = inflater.inflate(R.layout.item, parent, false);


            ViewHolder viewHolder = new ViewHolder();
            viewHolder.icon = (ImageView) rowView.findViewById(R.id.image);
            viewHolder.title = (TextView) rowView.findViewById(R.id.title);

            viewHolder.newimage =(WebView)rowView.findViewById(R.id.newimage);


            rowView.setTag(viewHolder);
        }

        ViewHolder holder = (ViewHolder) rowView.getTag();

        holder.title.setText(item.getmTitle());

        //String html = " <html><head></head><body><p font-size='8px'>" +  item.getmImageUrl() + "</p><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>";
        String html = " <html><head></head><body><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>";




        holder.newimage.loadData(html, "text/html", "utf-8");

        holder.newimage.setFocusable(false);
        holder.newimage.setClickable(false);
        holder.setOnClickListener(new OnItemClickListener() {

            private Object title;

            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                //Toast.makeText(Adapter.this,"Button is clicked", Toast.LENGTH_LONG).show();
                Log.e("log_tag",this.title.toString() + " clicked");
            }
        });

        //holder.icon.setBackgroundResource(R.drawable.ic_launcher);
        holder.mTask = new DownloadImageTask(item.getmImageUrl(), holder.icon);


        holder.icon.setImageBitmap(bitmapList[position]);

        //loadImageBitmap(mObjects.get(position), position);

        //onBitmapLoaded(position, holder.mTask.myBitmap());
        if (!holder.mTask.isCancelled()) {
            holder.mTask.execute();
        }


        return rowView;
    }

    @Override
    public int getCount() {

        return (this.mObjects.size());
    }

    @Override
    public Object getItem(int position) {

        return (this.mObjects.get(position));
    }

    @Override
    public long getItemId(int position) {

        return (position);
    }

    public AbsListView.RecyclerListener mRecyclerListener = new RecyclerListener( ){

        public void onMovedToScrapHeap(View view) {
            ViewHolder viewHolder = (ViewHolder) view.getTag();
            DownloadImageTask imagetask = viewHolder.mTask;
            if (imagetask != null) {
                imagetask.cancel(true);
            }
        }

    };

    public void setOnClickListener(OnItemClickListener onItemClickListener) {
        // TODO Auto-generated method stub

    }

DownloadImageTask.java

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
    public Bitmap g;
    private String mUrl;
    private ImageView mImageView = null;

    public DownloadImageTask(String Url, ImageView imageView) {

        mUrl = Url;
        this.mImageView = imageView;
    }

    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        if (result != null) {
            mImageView.setImageBitmap(result);
            //result.recycle();
        }
    }

    protected Bitmap doInBackground(Void... params) {

        Bitmap bitmap = getBitmap(mUrl);
        return bitmap;
    }

    public Bitmap getBitmap(String imageUrl) {
        Bitmap mBitmap = null;
        try {

            /*URL newurl = new URL(imageUrl); 
            mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */
            //mImageView.setImageBitmap(mBitmap);

            /*
            URL url = new URL(imageUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            InputStream is = conn.getInputStream();
            mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/


            InputStream in = new java.net.URL(imageUrl).openStream();
            mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in));
            //mBitmap.recycle();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.g = mBitmap;
        return mBitmap;
    }

    public Bitmap myBitmap() {
        Bitmap fg;
        fg = (Bitmap) g;

        return fg;
    }

    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

}

修改

我修改了DownloadImageTask.java,按照以下代码进行一些缓存:https://stackoverflow.com/a/7730547

但我似乎在这方面有问题:

if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) {
            /* The path is not same. This means that this
               image view is handled by some other async task. 
               We don't do anything and return. */
            return;
         }

由于if ...行,应用程序总是崩溃。这令人非常沮丧。我需要帮助。请帮我。下面是修改后的DownloadImageTask.Java

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ImageView;

public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
    public Bitmap g;
    private String mUrl;
    private ImageView mImageView = null;

    public DownloadImageTask(String Url, ImageView imageView) {


        mUrl = Url;
        this.mImageView = imageView;




    }

    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);

        /*
        if (result != null) {
            mImageView.setImageBitmap(result);

        }
        */
        if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) {
            /* The path is not same. This means that this
               image view is handled by some other async task. 
               We don't do anything and return. */
            return;
         }

         if(result != null && mImageView != null){
             mImageView.setVisibility(View.VISIBLE);
             mImageView.setImageBitmap(result);
             mImageView.setTag(this.mUrl);
         }else{
             mImageView.setVisibility(View.GONE);
         }


    }

    protected Bitmap doInBackground(Void... params) {

        Bitmap bitmap = getBitmap(mUrl);
        return bitmap;




    }

    public Bitmap getBitmap(String imageUrl) {


        Bitmap mBitmap = null;
        try {

            /*URL newurl = new URL(imageUrl); 
            mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */
            //mImageView.setImageBitmap(mBitmap);

            /*
            URL url = new URL(imageUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            InputStream is = conn.getInputStream();
            mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/


            InputStream in = new java.net.URL(imageUrl).openStream();
            mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in));


            //this.mImageView.setTag(this.mUrl);
            //mBitmap.recycle();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.g = mBitmap;

            return mBitmap;

    }

    public Bitmap myBitmap() {
        Bitmap fg;
        fg = (Bitmap) g;

        return fg;
    }

    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }






}

1 个答案:

答案 0 :(得分:0)

而不是使用AsyncTask手动实现此操作,您可以使用缓存库。 Android查询非常好:http://code.google.com/p/android-query/

要使用Android Query加载图像,您可以在ListView适配器的getView方法中使用以下代码:

AQuery _aq = new AQuery(mActivity);
_aq.id(R.id.icon).image("IMAGE_URI_TO_LOAD");

这应该取代holder.icon.setImageBitmap(bitmapList[position]);来电。

这将加载,缓存并在imageview中显示来自Uri的图像。如果图像已经缓存,则会从缓存中自动加载。

有关如何使用此库进行图像加载的详细信息,请访问以下网址:http://code.google.com/p/android-query/wiki/ImageLoading