如何在Android中通过URL加载ImageView?[关闭]


Answers:


713

来自Android开发人员

// show The Image in a ImageView
new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
            .execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");

public void onClick(View v) {
    startActivity(new Intent(this, IndexActivity.class));
    finish();

}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

确保您已设置以下AndroidManifest.xml访问互联网的权限。

<uses-permission android:name="android.permission.INTERNET" />

39
这太棒了。并且应该在列表上更高。asynctask允许加载它而不会冻结UI!
凯尔·克莱格

3
AsyncTasks使用一个串行执行器,这意味着每个图像将一次加载一个,而不是并行线程加载。
Blundell

2
源链接不再起作用了……
hevvd 2013年

10
在您的示例中,输入流未关闭。最好在try / catch的最后一块完成。
Risadinha

2
这种方法仍然有用吗?我对OnClick()方法及其用途感到困惑
tccpg288 '16

169

1. Picasso允许在您的应用程序中轻松加载图像-通常只需一行代码!

使用Gradle:

implementation 'com.squareup.picasso:picasso:2.71828'

只需一行代码!

Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);

2. 滑行 Android的图像加载和缓存库着重于平滑滚动

使用Gradle:

repositories {
  mavenCentral() 
  google()
}

dependencies {
   implementation 'com.github.bumptech.glide:glide:4.7.1'
   annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}

//对于一个简单的视图:

  Glide.with(this).load("http://i.imgur.com/DvpvklR.png").into(imageView);

3. fresco 是一个功能强大的系统,可在Android应用程序中显示图像。Fresco负责图像的加载和显示,因此您不必这样做。

壁画入门


2
因此,如果url为localhost,则表示映像位于开发系统的本地服务器数据库中,例如xampp,仍然无法从url =获取映像。
二十一点2014年

2
@blackjack-应用程序中的本地主机将是智能手机本身。要访问您的开发系统,智能手机和开发系统必须位于同一网络中,并且您必须在该网络中使用开发系统的IP地址。
Ridcully

1
是否可以使用毕加索在按钮上加载图像?
mahdi 2015年

1
@chiragkyada我尝试使用此代码Picasso.with(context).load(url).into(button_view); 但它`显示错误:到(button_view)
迈赫迪

1
我认为这应该是公认的答案
Udo 2015年

150

您必须先下载图像

public static Bitmap loadBitmap(String url) {
    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;

    try {
        in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);

        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
        copy(in, out);
        out.flush();

        final byte[] data = dataStream.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        //options.inSampleSize = 1;

        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
    } catch (IOException e) {
        Log.e(TAG, "Could not load Bitmap from: " + url);
    } finally {
        closeStream(in);
        closeStream(out);
    }

    return bitmap;
}

然后使用Imageview.setImageBitmap将位图设置为ImageView


126
你是对的。但是只有这3条线可以解决问题。URL newurl =新URL(photo_url_str); mIcon_val = BitmapFactory.decodeStream(newurl.openConnection().getInputStream()); profile_photo.setImageBitmap(mIcon_val); 感谢您的答复。
Praveen

2
对于URL-导入java.net.URL; 私有静态最终int IO_BUFFER_SIZE = 4 * 1024; 最后一个是什么?
史蒂夫


@SACPK,您应该在评论中写下您的评论,以便其获得投票
Jim Wallace

答案对我来说是正确的,将其发布为答案:)
omn​​ia Mm

71

我编写了一个类来处理此问题,因为在我的各个项目中似乎都反复出现这种需求:

https://github.com/koush/UrlImageViewHelper

UrlImageViewHelper将使用URL中找到的图像填充ImageView。

该示例将执行Google图片搜索并异步加载/显示结果。

UrlImageViewHelper将自动下载,保存和缓存BitmapDrawables的所有图像URL。重复的网址不会两次加载到内存中。位图内存是通过使用弱引用哈希表来管理的,因此一旦您不再使用该图像,就会自动对其进行垃圾回收。


顺便问一下,这有什么许可?
Ehtesh Choudhury

@Shurane-Apache。我稍后会记下它。
koush 2012年

1
似乎我们需要改用github.com/koush/ion,因为不推荐使用UrlImageViewHelper,如github.com/koush/UrlImageViewHelper上的github项目页面所示
Svetoslav Marinov 2015年

69

无论如何,人们要求我发表评论以作为答案。我正在发布。

URL newurl = new URL(photo_url_str); 
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection().getInputStream());
profile_photo.setImageBitmap(mIcon_val);

这是短暂而伟大的,谢谢
Nactus 2014年

18
毫米..但是这不能从UI线程完成。
Guy

2
对于遇到“格式错误的网址错误”的问题的人,请尝试/捕获以上内容。stackoverflow.com/a/24418607/2093088
Riot Gos Woof

1
这应该使用如上所述的AsyncTask完成
B-GangsteR

63

如果您是通过单击按钮加载图像的,则上面接受的答案很好,但是,如果您在新活动中进行图像加载,则会冻结UI一两秒钟。环顾四周,我发现一个简单的asynctask消除了这个问题。

要使用asynctask,请在活动结束时添加此类:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }    
}

并使用以下方法从onCreate()方法进行调用:

new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
        .execute(MY_URL_STRING);

结果是快速加载的活动和一个图像视图,稍后根据用户的网络速度显示一秒钟。


这既快速又紧凑。很好地满足了我的需求!谢谢!
马克·墨菲

截至我的时间戳,这对我有用!
Carpk

25

您还可以使用此LoadingImageView视图从url加载图像:

http://blog.blundellapps.com/imageview-with-loading-spinner/

一旦从该链接添加了类文件,就可以实例化url图像视图:

在xml中:

<com.blundell.tut.LoaderImageView
  android:id="@+id/loaderImageView"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  image="http://developer.android.com/images/dialog_buttons.png"
 />

在代码中:

final LoaderImageView image = new LoaderImageView(this, "http://developer.android.com/images/dialog_buttons.png");

并使用以下命令更新它:

image.setImageDrawable("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");

很好的示例,但是我不认为这是线程安全的。我正在尝试在Async onPostExecute中使用它,但是onPostExecute有时可能在接收到回调并呈现空图像之前结束。
吉米

这管理着它自己的线程。因此,为什么不让ASyncTask在完成后使用所需的URL回调到UI。这样,您就没有线程产生线程了。
Blundell,2012年

10
public class LoadWebImg extends Activity {

String image_URL=
 "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png";

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       ImageView bmImage = (ImageView)findViewById(R.id.image);
    BitmapFactory.Options bmOptions;
    bmOptions = new BitmapFactory.Options();
    bmOptions.inSampleSize = 1;
    Bitmap bm = LoadImage(image_URL, bmOptions);
    bmImage.setImageBitmap(bm);
   }

   private Bitmap LoadImage(String URL, BitmapFactory.Options options)
   {       
    Bitmap bitmap = null;
    InputStream in = null;       
       try {
           in = OpenHttpConnection(URL);
           bitmap = BitmapFactory.decodeStream(in, null, options);
           in.close();
       } catch (IOException e1) {
       }
       return bitmap;               
   }

private InputStream OpenHttpConnection(String strURL) throws IOException{
 InputStream inputStream = null;
 URL url = new URL(strURL);
 URLConnection conn = url.openConnection();

 try{
  HttpURLConnection httpConn = (HttpURLConnection)conn;
  httpConn.setRequestMethod("GET");
  httpConn.connect();

  if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
   inputStream = httpConn.getInputStream();
  }
 }
 catch (Exception ex)
 {
 }
 return inputStream;
}
}

非常感谢,我一直在寻找一个完美的例子.......,但是在错误的主题下,这应该在这里==> 如何从字符串设置imageView的图像?
VenomVendor 2012年

10

嗨,我有最简单的代码,试试看

    public class ImageFromUrlExample extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);  
            ImageView imgView =(ImageView)findViewById(R.id.ImageView01);
            Drawable drawable = LoadImageFromWebOperations("http://www.androidpeople.com/wp-content/uploads/2010/03/android.png");
            imgView.setImageDrawable(drawable);

    }

    private Drawable LoadImageFromWebOperations(String url)
    {
          try{
        InputStream is = (InputStream) new URL(url).getContent();
        Drawable d = Drawable.createFromStream(is, "src name");
        return d;
      }catch (Exception e) {
        System.out.println("Exc="+e);
        return null;
      }
    }
   }

main.xml

  <LinearLayout 
    android:id="@+id/LinearLayout01"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
   <ImageView 
       android:id="@+id/ImageView01"
       android:layout_height="wrap_content" 
       android:layout_width="wrap_content"/>

尝试这个



9

我最近在这里找到了一个线程,因为我必须对带有图像的listview做类似的事情,但是原理很简单,因为您可以在其中显示的第一个示例类中阅读(由jleedev编写)。您可以从网络获取图像的输入流

private InputStream fetch(String urlString) throws MalformedURLException, IOException {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpGet request = new HttpGet(urlString);
    HttpResponse response = httpClient.execute(request);
    return response.getEntity().getContent();
}

然后,将图像存储为Drawable,并将其传递给ImageView(通过setImageDrawable)。再次从上面的代码片段中查看整个线程。

InputStream is = fetch(urlString);
Drawable drawable = Drawable.createFromStream(is, "src");

我的项目中没有DefaultHttpClient。
Stepan Yakovenko


7

这是一个较晚的答复,正如上面所建议的那样AsyncTask,在谷歌搜索了一下之后,我发现了解决此问题的另一种方法。

Drawable drawable = Drawable.createFromStream((InputStream) new URL("url").getContent(), "src");

imageView.setImageDrawable(drawable);

这是完整的功能:

public void loadMapPreview () {
    //start a background thread for networking
    new Thread(new Runnable() {
        public void run(){
            try {
                //download the drawable
                final Drawable drawable = Drawable.createFromStream((InputStream) new URL("url").getContent(), "src");
                //edit the view in the UI thread
                imageView.post(new Runnable() {
                    public void run() {
                        imageView.setImageDrawable(drawable);
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

不要忘记在您AndroidManifest.xml的互联网中添加以下权限。

<uses-permission android:name="android.permission.INTERNET" />

我自己尝试过,还没有遇到任何问题。


实际上,这对于极简主义非常好!请记住,Thread由于UI线程不允许进行网络操作,因此需要额外运行。
creativecreatoror可能

6
imageView.setImageBitmap(BitmapFactory.decodeStream(imageUrl.openStream()));//try/catch IOException and MalformedURLException outside

5

这将帮助您...

定义imageview并将图像加载到其中。

Imageview i = (ImageView) vv.findViewById(R.id.img_country);
i.setImageBitmap(DownloadFullFromUrl(url));

然后定义此方法:

    public Bitmap DownloadFullFromUrl(String imageFullURL) {
    Bitmap bm = null;
    try {
        URL url = new URL(imageFullURL);
        URLConnection ucon = url.openConnection();
        InputStream is = ucon.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int current = 0;
        while ((current = bis.read()) != -1) {
            baf.append((byte) current);
        }
        bm = BitmapFactory.decodeByteArray(baf.toByteArray(), 0,
                baf.toByteArray().length);
    } catch (IOException e) {
        Log.d("ImageManager", "Error: " + e);
    }
    return bm;
}


4

具有异常处理和异步任务的版本:

AsyncTask<URL, Void, Boolean> asyncTask = new AsyncTask<URL, Void, Boolean>() {
    public Bitmap mIcon_val;
    public IOException error;

    @Override
    protected Boolean doInBackground(URL... params) {
        try {
            mIcon_val = BitmapFactory.decodeStream(params[0].openConnection().getInputStream());
        } catch (IOException e) {
            this.error = e;
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean success) {
        super.onPostExecute(success);
        if (success) {
            image.setImageBitmap(mIcon_val);
        } else {
            image.setImageBitmap(defaultImage);
        }
    }
};
try {
    URL url = new URL(url);
    asyncTask.execute(url);
} catch (MalformedURLException e) {
    e.printStackTrace();
}

3
    private Bitmap getImageBitmap(String url) {
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
       } catch (IOException e) {
           Log.e(TAG, "Error getting bitmap", e);
       }
       return bm;
    } 


3

这段代码已经过测试,可以完全正常工作。

URL req = new URL(
"http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png"
);
Bitmap mIcon_val = BitmapFactory.decodeStream(req.openConnection()
                  .getInputStream());

3

在任何容器中使用imageView,例如listview网格视图,常规布局

 private class LoadImagefromUrl extends AsyncTask< Object, Void, Bitmap > {
        ImageView ivPreview = null;

        @Override
        protected Bitmap doInBackground( Object... params ) {
            this.ivPreview = (ImageView) params[0];
            String url = (String) params[1];
            System.out.println(url);
            return loadBitmap( url );
        }

        @Override
        protected void onPostExecute( Bitmap result ) {
            super.onPostExecute( result );
            ivPreview.setImageBitmap( result );
        }
    }

    public Bitmap loadBitmap( String url ) {
        URL newurl = null;
        Bitmap bitmap = null;
        try {
            newurl = new URL( url );
            bitmap = BitmapFactory.decodeStream( newurl.openConnection( ).getInputStream( ) );
        } catch ( MalformedURLException e ) {
            e.printStackTrace( );
        } catch ( IOException e ) {

            e.printStackTrace( );
        }
        return bitmap;
    }
/** Usage **/
  new LoadImagefromUrl( ).execute( imageView, url );

+1感谢您提供完整,便捷的解决方案。
PeteH 2014年

3

尝试这种方式,希望这将帮助您解决问题。

在这里,我解释了如何使用“ AndroidQuery”外部库以asyncTask方式从url /服务器加载图像,并且还将加载的图像缓存到设备文件或缓存区域。

  • 从这里下载“ AndroidQuery”库
  • 复制/粘贴此jar到project lib文件夹,然后将此库添加到project build-path
  • 现在,我演示如何使用它的演示。

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/imageFromUrl"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"/>
            <ProgressBar
                android:id="@+id/pbrLoadImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"/>

        </FrameLayout>
    </LinearLayout>

MainActivity.java

public class MainActivity extends Activity {

private AQuery aQuery;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    aQuery = new AQuery(this);
    aQuery.id(R.id.imageFromUrl).progress(R.id.pbrLoadImage).image("http://itechthereforeiam.com/wp-content/uploads/2013/11/android-gone-packing.jpg",true,true);
 }
}

Note : Here I just implemented common method to load image from url/server but you can use various types of method which can be provided by "AndroidQuery"to load your image easily.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.