在安卓上为ImageView下载图片

5
我看到了这个问题:android如何下载一个1MB的图像文件并将其设置为ImageView
它没有解决我的问题,因为它只展示了如何在你已经拥有图片后显示位图。
我正在尝试从URL下载一张图片,并在Android设备上用ImageView显示它。我不确定该怎么做。
我在互联网上查找了一些资料,这是我到目前为止的代码:
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //Set local image
    ImageView image = (ImageView) findViewById(R.id.test_image);
    image.setImageResource(R.drawable.test2);

    //Prepare to download image
    URL url;        
    InputStream in;

    //BufferedInputStream buf;
    try {
        url = new URL("http://i.imgur.com/CQzlM.jpg");
        in = url.openStream();

        out = new BufferedOutputStream(new FileOutputStream("testImage.jpg"));
        int i;

         while ((i = in.read()) != -1) {
             out.write(i);
         }
         out.close();
         in.close();

        buf = new BufferedInputStream(in);
        Bitmap bMap = BitmapFactory.decodeStream(buf);
        image.setImageBitmap(bMap);
        if (in != null) {
        in.close();
        }
        if (buf != null) {
        buf.close();
        }
    } catch (Exception e) {
        Log.e("Error reading file", e.toString());
    }
}

如果你找到了答案,应该接受它。这样其他用户就知道它是有效的。祝好运! - Entreco
1个回答

11

这段代码可能会运行成功,尽管你正在主线程上下载图像。这意味着如果下载时间超过5秒钟,你将会看到著名的ANR对话框,你的应用程序将崩溃...

你应该在后台线程中下载图像,并将结果发布回主线程。在主线程中,你可以使用已下载的图像更新你的ImageView。

这里有一个例子:

package nl.entreco.stackoverflow;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

public class StackOverflowActivity extends Activity {

//  
private ImageView mImageView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //Find the reference to the ImageView
    mImageView = (ImageView) findViewById(R.id.test_image);

    // You can set a temporary background here
    //image.setImageResource(null);

    // Start the DownloadImage task with the given url
    new DownloadImage().execute("http://i.imgur.com/CQzlM.jpg");
}


/**
 * Simple functin to set a Drawable to the image View
 * @param drawable
 */
private void setImage(Drawable drawable)
{
    mImageView.setBackgroundDrawable(drawable);
}

public class DownloadImage extends AsyncTask<String, Integer, Drawable> {

    @Override
    protected Drawable doInBackground(String... arg0) {
        // This is done in a background thread
        return downloadImage(arg0[0]);
    }

    /**
     * Called after the image has been downloaded
     * -> this calls a function on the main thread again
     */
    protected void onPostExecute(Drawable image)
    {
        setImage(image);
    }


    /**
     * Actually download the Image from the _url
     * @param _url
     * @return
     */
    private Drawable downloadImage(String _url)
    {
        //Prepare to download image
        URL url;        
        BufferedOutputStream out;
        InputStream in;
        BufferedInputStream buf;

        //BufferedInputStream buf;
        try {
            url = new URL(_url);
            in = url.openStream();

            /*
             * THIS IS NOT NEEDED
             * 
             * YOU TRY TO CREATE AN ACTUAL IMAGE HERE, BY WRITING
             * TO A NEW FILE
             * YOU ONLY NEED TO READ THE INPUTSTREAM 
             * AND CONVERT THAT TO A BITMAP
            out = new BufferedOutputStream(new FileOutputStream("testImage.jpg"));
            int i;

             while ((i = in.read()) != -1) {
                 out.write(i);
             }
             out.close();
             in.close();
             */

            // Read the inputstream 
            buf = new BufferedInputStream(in);

            // Convert the BufferedInputStream to a Bitmap
            Bitmap bMap = BitmapFactory.decodeStream(buf);
            if (in != null) {
                in.close();
            }
            if (buf != null) {
                buf.close();
            }

            return new BitmapDrawable(bMap);

        } catch (Exception e) {
            Log.e("Error reading file", e.toString());
        }

        return null;
    }

}

}

如果您没有在清单文件中添加 permission.INTERNET 权限,那么请不要忘记添加它,否则将会出现错误...


我尝试过了。它没有报错,但是图片无法加载。在AndroidManifest.xml文件中存在Internet权限。这可能与DownloadImage类位于其他类内有关吗? - Koen027
没关系,我稍微改了一下代码就好了。在函数setImage中,我把唯一的一行改成了:mImageView.setImageDrawable(drawable); - Koen027
抱歉让你等了,测试完之后就忘记了这件事。 - Koen027
函数setBackgoundDrawable已经被弃用,改为使用setBackground。 - Rajan Chauhan

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