通过AsyncTask下载图片并在ImageView中显示,而不将其存储在SD卡中。

3

我希望通过 AsyncTask 下载图像,并在ImageView中显示它,我通常可以做到这点,但我还想向用户显示进度,而且这一切都不需要将文件存储在SD卡中。

以下是我目前所做的:

class DownloadFileFromURL extends AsyncTask<String, String, String> {

/**
 * Before starting background thread
 * Show Progress Bar Dialog
 * */
@Override
protected void onPreExecute() {
    super.onPreExecute();
    showDialog(progress_bar_type);
}

/**
 * Downloading file in background thread
 * */
@Override
protected String doInBackground(String... f_url) {
    int count;
    try {
        URL url = new URL(f_url[0]);
        URLConnection conection = url.openConnection();
        conection.connect();
        // getting file length
        int lenghtOfFile = conection.getContentLength();

        // input stream to read file - with 8k buffer
        InputStream input = new BufferedInputStream(url.openStream(), 8192);

        // Output stream to write file
        OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");

        byte data[] = new byte[1024];

        long total = 0;

        while ((count = input.read(data)) != -1) {
            total += count;
            // publishing the progress....
            // After this onProgressUpdate will be called
            publishProgress(""+(int)((total*100)/lenghtOfFile));

            // writing data to file
            output.write(data, 0, count);
        }

        // flushing output
        output.flush();

        // closing streams
        output.close();
        input.close();

    } catch (Exception e) {
        Log.e("Error: ", e.getMessage());
    }

    return null;
}

/**
 * Updating progress bar
 * */
protected void onProgressUpdate(String... progress) {
    // setting progress percentage
    pDialog.setProgress(Integer.parseInt(progress[0]));
}

/**
 * After completing background task
 * Dismiss the progress dialog
 * **/
@Override
protected void onPostExecute(String file_url) {
    // dismiss the dialog after the file was downloaded
    dismissDialog(progress_bar_type);

    // Displaying downloaded image into image view
    // Reading image path from sdcard
    String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
    // setting downloaded into image view
    my_image.setImageDrawable(Drawable.createFromPath(imagePath));
}

}

你能解释一下你的代码出了什么问题吗? - L. Swifter
如果我将下载的图像保存在本地,那么一切都正常,但是如果我使用位图,则进度条工作正常,但图像不会显示。 - Ezio
你应该使用ByteArrayOutputStreamBitmapFactory.decodeByteArray来实现你的目的。 - L. Swifter
3个回答

1
您可以使用Glide代替:
Glide.with(this).load("http://server.com/image.jpg").into(imageView);

感谢您告知我们这个库。 - Ezio

1
如果您不想将图像下载到本地,应该使用ByteArrayOutputStream而不是FileOutputStream。以下是关键代码:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
    total += count;
    publishProgress(""+(int)((total*100)/lenghtOfFile));

    outputStream.write(data, 0, count);
}

//after downloading the image
byte[] imageData = outputStream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
my_image.setImageBitmap(bitmap);

我没有测试过,但我相信这可以帮助你。


非常感谢,它像魔法一样运行良好。(因声望不足,无法点赞:( ) - Ezio
很高兴能帮忙 :) - L. Swifter

0

参考 Android中从URL下载图像的最佳方法

private Bitmap downloadBitmap(String url) {
        HttpURLConnection urlConnection = null;
        try {
            URL uri = new URL(url);
            urlConnection = (HttpURLConnection) uri.openConnection();

            int statusCode = urlConnection.getResponseCode();
            if (statusCode != HttpStatus.SC_OK) {
                return null;
            }

            InputStream inputStream = urlConnection.getInputStream();
            if (inputStream != null) {

                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            }
        } catch (Exception e) {
            Log.d("URLCONNECTIONERROR", e.toString());
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            Log.w("ImageDownloader", "Error downloading image from " + url);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();

            }
        }
        return null;
    }

我正在做同样的事情,但我还必须向用户显示进度,而在这方面我遇到了问题。 - Ezio
你可以使用createTempFile函数创建临时文件,或者在外部/内部目录中写入文件。 - Ramit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接