通过 AsyncTask 下载图像并将其显示在 Imageview 中而不存储在 sdcard 中

Posted

技术标签:

【中文标题】通过 AsyncTask 下载图像并将其显示在 Imageview 中而不存储在 sdcard 中【英文标题】:Downloading Image Via AsyncTask and displaying it in an Imageview without storing in sdcard 【发布时间】:2016-12-20 18:59:16 【问题描述】:

我想通过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 如果我将下载的图像保存在本地,那么一切都可以正常工作,但如果我使用位图,那么进度条可以正常工作,但图像不显示 你应该使用ByteArrayOutputStreamBitmapFactory.decodeByteArray来达到你的目的。 【参考方案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);

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

【讨论】:

非常感谢它的作用就像一个魅力。(由于缺乏声誉,无法投票:() 乐于助人:)【参考方案2】:

参考Best method to download image from url in android

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;
    

【讨论】:

我也在做同样的事情,但我还必须向用户显示进度,我遇到了问题。 您可以使用createTempFile,或者在外部/内部目录中写入文件【参考方案3】:

您可以改用 Glide

Glide.with(this).load("http://server.com/image.jpg").into(imageView);

【讨论】:

感谢您让我们知道这个图书馆

以上是关于通过 AsyncTask 下载图像并将其显示在 Imageview 中而不存储在 sdcard 中的主要内容,如果未能解决你的问题,请参考以下文章

Android - 在显示进度时将图像从 URL 加载到 ImageView(不保存图像)

Android AsyncTask 等待完成以检索数据并将其显示在 ListView

NullPointerException 与 android AsyncTask 和 RecyclerView

从网络加载图像并将其显示在集合视图中

通过(From)AsyncTask 向 MainActivity 发送意图

如何从 Firebase 存储中下载图像并将其存储在颤动的列表中 [关闭]