如何在 ListView 中无延迟地从网络下载图像?

发布于 2024-11-03 03:21:39 字数 2016 浏览 1 评论 0原文

我有一个 ListAdapter,其中包含一堆从互联网下载的图像。当我上下滚动时,性能似乎受到了影响,并且事情变得不稳定。我该如何解决这个问题?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

记忆里有你的影子 2024-11-10 03:21:39

使用图像的延迟加载 - 延迟加载ListView 中的图像

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

千笙结 2024-11-10 03:21:39

也许通过使用线程池(队列)并同时放置临时图像?

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

爱*していゐ 2024-11-10 03:21:39

这是一个很好的方法。

至少我认为它很好。我做到了:)

这是我用来在后台加载 ImageView 的类。

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

然后当你想使用它时,你会这样称呼它。

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

并将imView发送到UI。下载时它会加载图像。

请给我您诚实的反馈。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文