Как скачать и отобразить растровые изображения с AsyncTask - PullRequest
1 голос
/ 04 апреля 2011

Я новичок с 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

<code>
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 

Когда я щелкаю элемент в ListView в ActivityA, он правильно переходит к ActivityB, и ActivityB показывает изображения. Когда я нажимаю кнопку «Назад» на ActivityB, чтобы выполнить резервное копирование до ActivityA, затем снова нажимаю на элемент в ListView, я прихожу к ActivityB и затем вижу, что мне сообщили, что процесс неожиданно закрылся. *

При попытке отладки я заметил, что проблема в linE:

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

Который находится в функции protected Bitmap downloadBitmap(String url).

Я читал об ошибке в Android с BitmapFactory.decodeStream, поэтому я добавил FlushedInputStream, чтобы предотвратить ее.

Однако мне кажется, что это не является причиной проблемы, поскольку она работала при первой загрузке ActivityB, но не во второй раз. Может у меня утечка памяти? (Изображения большие, и память не перезагружается после возврата на ActivityA.)

Если так, как я могу очистить связанную память? Или проблема в чем-то другом?

Для справки: мои изображения в формате .jpg, я пытался преобразовать их в .png , но у меня были те же проблемы.

1 Ответ

0 голосов
/ 05 мая 2014

Вы должны использовать библиотеку загрузки изображений, например Picasso или Volley, чтобы выполнить тяжелую работу за вас.

...