【问题标题】:How to download and display bitmaps with AsyncTask如何使用 AsyncTask 下载和显示位图
【发布时间】:2011-07-29 08:36:02
【问题描述】:

我是 android 新手,最近几天我找不到问题的原因:

我有 ActivityA 和 ListView。单击该 ListView 中的每个项目将打开 ActivityB, 这将在ImageView 中显示一些从网络下载的图像。 因此,在ActivityB 中,我使用以下代码循环尝试下载图像:

ImageView ivPictureSmall = new ImageView(this);
ImageDownloader ido = new ImageDownloader();
ido.download(this.getResources().getString(R.string.images_uri) + strPictureSmall, ivPictureSmall);
ivPictureSmall.setPadding(3, 5, 3, 5);
linearLayout.addView(ivPictureSmall);

类 ImageDownloader


public class ImageDownloader
{
    public void download(String url, ImageView imageView)
    {
            BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
            task.execute(url);
    }
}

类 BitmapDownloaderTask


class BitmapDownloaderTask extends AsyncTask
{
    private String url;
    private final WeakReference imageViewReference;

    public BitmapDownloaderTask(ImageView imageView)
    {
        imageViewReference = new WeakReference(imageView);
    }

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params)
    {
        // params comes from the execute() call: params[0] is the url.
        return downloadBitmap(params[0]);
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap)
    {
        if (isCancelled())
        {
            bitmap = null;
        }

        if (imageViewReference != null)
        {
            ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }

    }

    protected Bitmap downloadBitmap(String url)
    {
        final DefaultHttpClient client = new DefaultHttpClient();
        final HttpGet getRequest = new HttpGet(url);

        try {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
                return null;
            }
            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    inputStream = entity.getContent();
                    final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
                    return bitmap;
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        } catch (Exception e) {
            // Could provide a more explicit error message for IOException or IllegalStateException
            getRequest.abort();
            Log.w("ImageDownloader", "Error while retrieving bitmap from: " + e.toString());
        } finally {
            if (client != null) {
                //client.close();

            }
        }
        return null;
    }


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

        @Override
        public long skip(long n) throws IOException
        {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped 

当我在 ActivityA 中单击 ListView 中的一个项目时,它正确地转到 ActivityB,并且 ActivityB 显示图像。当我按ActivityB 上的“返回”按钮备份到ActivityA,然后再次单击ListView 中的某个项目时,我来到ActivityB,然后我看到被告知进程意外关闭。

当我尝试调试时,我注意到问题出在 lineE:

final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream));

protected Bitmap downloadBitmap(String url) 函数中。

我通过BitmapFactory.decodeStream 读到了Android 中的一个错误,所以我添加了FlushedInputStream 来防止它。

但是,在我看来这不是问题的原因,因为它在我第一次加载 ActivityB 时工作,但不是第二次。也许我有内存泄漏? (图片很大,回ActivityA后不回收内存。)

如果是这样,我该如何清理相关的内存?还是有其他问题?

供参考:我的图片是.jpg 格式,我尝试将它们转换为.png,但遇到了同样的问题。

【问题讨论】:

  • 你的问题太长了。您要求人们为您调试代码,而大多数人没有时间...
  • 好吧,我试图提供所有相关信息.. 我认为代码中有一些明显的问题,我没有看到,因为我是 android 和 java 的新手。
  • 你应该添加 system.gc() 来释放内存

标签: android memory download bitmap android-asynctask


【解决方案1】:

您应该使用像 PicassoVolley 这样的图像加载库来为您完成这项艰巨的工作。

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 2012-11-06
    • 2017-05-16
    • 1970-01-01
    相关资源
    最近更新 更多