0

I have a ListAdapter that contains a bunch of images that are being downloaded from the internet. When I scroll up and down there seems to be a performance hit and things get jerky. How can I resolve this?

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.message_row, null);
            }

            STMessage aMessage = messages.get(position);

            if (aMessage != null) {
                TextView usernameTextView = (TextView) v.findViewById(R.id.usernameTextView);
                TextView bodyTextView = (TextView) v.findViewById(R.id.bodyTextView);
                TextView dateTextView = (TextView) v.findViewById(R.id.dateTextView);
                ImageView avatarImageView = (ImageView)v.findViewById(R.id.avatarImageView);

                if (usernameTextView != null) {
                    usernameTextView.setText(Html.fromHtml(aMessage.getUser_login()));
                }
                if (bodyTextView != null) {
                    bodyTextView.setText(aMessage.getBody());

                    //linkify urls
                    Linkify.addLinks(bodyTextView, Linkify.WEB_URLS);


                    //linkify symbols
                    Pattern symbolMatcher = Pattern.compile("/(?:^|\\s|[\\.(\\+\\-\\,])(?:\\$?)\\$((?:[0-9]+(?=[a-z])|(?![0-9\\.\\:\\_\\-]))(?:[a-z0-9]|[\\_\\.\\-\\:](?![\\.\\_\\.\\-\\:]))*[a-z0-9]+)/i");
                    String symbolURL =    "content://com.stocktwits.activity/symbol/";
                    Linkify.addLinks(bodyTextView, symbolMatcher, symbolURL);
                }
                if (dateTextView != null) {
                    dateTextView.setText(aMessage.getUpdated_at());
                }

                if (avatarImageView != null) {
                    imageDownloader.download(aMessage.getAvatar_url(), avatarImageView);
                }
            }

            return v;
        }
Sheehan Alam
  • 60,111
  • 124
  • 355
  • 556

3 Answers3

4

Use Lazy Loading of Images - Lazy load of images in ListView

Community
  • 1
  • 1
Rajath
  • 11,787
  • 7
  • 48
  • 62
0

Maybe by using a Threads pool (queue) and placing a temporal image in the meantime?

Vicente Plata
  • 3,370
  • 1
  • 19
  • 26
0

Here is a nice way to go about it.

At least I think its nice. I did it :)

here is the class I used to load the ImageView in the background.

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    private ImageView destination;
    private String cachedFile;
    private Date startTime; 
    private DownloadCompletedListener completedListener; 

    public DownloadImageTask(ImageView destination, String cachedFile, DownloadCompletedListener completedListener)
    {
        this.destination = destination;
        this.cachedFile = cachedFile;
        this.startTime = new Date();
        this.completedListener = completedListener;
    }

    protected Bitmap doInBackground(String... urls) 
    {
        Bitmap result = getBitmapFromURL(urls[0]);
        if (result != null)
        {
            try {
            FileOutputStream out = new FileOutputStream(HSAppUtil.getFilePath(getFilenameFromUrl(urls[0])));
                result.compress(Bitmap.CompressFormat.PNG, 90, out);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else
        {
            result = Bitmap.createBitmap(1,1,Config.ARGB_8888);
        }
        return result;
    }

    public String getHost() {
        return "http://MyMainHost";
    }

    public Bitmap getBitmapFromURL(String fileUrl) {
        String newFileUrl = null;
        if (!fileUrl.contains("://"))
        {
            newFileUrl = getHost() + fileUrl;
        }
        else
        {
            newFileUrl = fileUrl;
        }
        URL myFileUrl = null;
        try {
            myFileUrl = new URL(newFileUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        try {
            HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            int length = conn.getContentLength();
            InputStream is = conn.getInputStream();
            length++;
            return BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    protected void onPostExecute(Bitmap result) 
    {
        synchronized (destination) 
        {
            Date lastUpdated = (Date)destination.getTag();

            if (lastUpdated == null || lastUpdated.before(startTime))
            {
                boolean handled = false;

                if (completedListener != null)
                {
                    handled = completedListener.handleDownloadCompleted(destination, result);
                }   
                if (!handled && destination != null)
                {
                    destination.setTag(startTime);
                    destination.setImageBitmap(result);
                }
            }   
            result = null;
        }
    }

    public interface DownloadCompletedListener {
        boolean handleDownloadCompleted(ImageView i, Bitmap b);
    }
}

then when you want to use it, You would call it like this.

new DownloadImageTask(imView, fileUrl, completedListener).execute(fileUrl);

and send the imView to the UI. it will load the image in when it downloads it.

Please give me your honest feedback.

The Lazy Coder
  • 11,560
  • 4
  • 51
  • 69
  • I am using this class to download the images. It is a bit jerky when scrolling. – Sheehan Alam Apr 25 '11 at 06:19
  • if you call it with the execute method, then it should not be jerky.... there is no caching built into this class, but it would not be difficult to implement from here. I just have not done that yet. – The Lazy Coder Apr 25 '11 at 06:59