【问题标题】:How to load an ImageView by URL in Android? [closed]如何在 Android 中通过 URL 加载 ImageView? [关闭]
【发布时间】:2011-01-29 03:21:16
【问题描述】:

如何使用ImageView 中的 URL 引用的图像?

【问题讨论】:

  • public class ImageDownloader { private final Executor executor = Executors.newSingleThreadExecutor(); public void download(String url, Consumer onSuccess, Consumer onError) { Handler handler = new Handler(); executor.execute(() -> { try (InputStream in = new URL(url).openStream()) { 位图结果 = BitmapFactory.decodeStream(in); handler.post(() -> onSuccess.accept(result)) ; } catch (Exception e) { handler.post(() -> onError.accept(e)); } }); } }

标签: android bitmap imageview


【解决方案1】:

来自Android developer

// 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" />

【讨论】:

  • 这太棒了。并且应该在名单上更高。 asynctask 允许在不冻结 UI 的情况下加载它!
  • AsyncTasks 使用串行执行器,这意味着每个图像将一次加载一个,而不是并行线程加载。
  • 源链接不再起作用...
  • 在您的示例中输入流未关闭。最好在 try/catch 的 finally 块中完成。
  • 这个方法还有用吗?我对 OnClick() 方法及其用途有点困惑
【解决方案2】:

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

使用 Gradle:

implementation 'com.squareup.picasso:picasso:(insert latest version)'

只需一行代码!

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

2. Glide 一个专注于平滑滚动的 Android 图像加载和缓存库

使用 Gradle:

repositories {
   mavenCentral() 
   google()
}

dependencies {
   implementation 'com.github.bumptech.glide:glide:4.11.0'
   annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
// For a simple view:
Glide.with(this).load("http://i.imgur.com/DvpvklR.png").into(imageView);

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

Getting Started with Fresco

【讨论】:

  • 所以如果 url 是 localhost,意味着图像在开发系统本地服务器数据库中,例如 xampp,我仍然可以从 url = 获取图像。
  • @blackjack -- 应用程序中的 localhost 将是智能手机本身。要访问您的开发系统,智能手机和您的开发系统必须在同一网络中,并且您必须在该网络中使用您的开发系统的 IP 地址。
  • 是否可以使用毕加索在按钮上加载图像?
  • @chiragkyada 我尝试使用此代码 Picasso.with(context).load(url).into(button_view);但它显示错误:进入(button_view)
  • 我认为这应该是公认的答案
【解决方案3】:

你必须先下载图片

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 中

【讨论】:

  • 你说得对。但只有这 3 行有助于解决问题。 URL newurl = 新 URL(photo_url_str); mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); profile_photo.setImageBitmap(mIcon_val);谢谢你的回复。
  • 对于 URL - 导入 java.net.URL;私有静态最终 int IO_BUFFER_SIZE = 4 * 1024;最后一个是什么?
  • @SACPK 你应该写下你的评论作为答案,这样它就可以被投票了
  • 嘿@steve 不要小看自己! :) 我找到了伪代码部分的实现。这一行“copy(in, out)”必须替换为: int bytesRead;字节[]缓冲区=新字节[IO_BUFFER_SIZE]; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); }
【解决方案4】:

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

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

【讨论】:

  • 这很简短,谢谢
  • mm.. 这不能从 UI 线程完成。
  • 对于遇到“格式错误的 URL Exeption”问题的人,请将上面的行括在 try/catch 中。 stackoverflow.com/a/24418607/2093088
  • 这应该使用 AsyncTask 完成,如上所述
【解决方案5】:

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

https://github.com/koush/UrlImageViewHelper

UrlImageViewHelper 将填充一个 带有找到的图像的 ImageView 在 URL 上。

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

UrlImageViewHelper 会自动 下载、保存和缓存所有 图像 urls BitmapDrawables。 不会加载重复的网址 记忆两次。位图内存被管理 通过使用弱引用哈希表, 所以一旦图像不再 被你用了,就是垃圾 自动收集。

【讨论】:

【解决方案6】:

如果您基于按钮单击加载图像,上面接受的答案非常好,但是如果您在新活动中执行此操作,它会使 UI 冻结一两秒钟。环顾四周,我发现一个简单的异步任务消除了这个问题。

要使用异步任务,请在活动结束时添加此类:

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);

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

【讨论】:

  • 这既快速又紧凑。很好地满足了我的需求!谢谢!
  • 就我的时间戳而言,这对我有用!
【解决方案7】:

您还可以使用此 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");

【讨论】:

  • 不错的示例,但我不相信这是线程安全的。我正在尝试在异步 onPostExecute 中使用它,但是 onPostExecute 有时可能会在收到回调之前结束,呈现空图像。
  • 这管理它自己的线程。那么为什么不让你的 ASyncTask 在完成后用你想要的 url 回调 UI。这样你就没有线程产生线程。
【解决方案8】:

在我看来,完成此类任务的最佳现代图书馆是 Square 的 Picasso。它允许使用单线通过 URL 将图像加载到 ImageView:

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

【讨论】:

    【解决方案9】:
    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;
    }
    }
    

    【讨论】:

    • 非常感谢,我一直在寻找的完美示例....... 987654321@
    【解决方案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"/>
    

    试试这个

    【讨论】:

      【解决方案11】:

      我最近发现了一个线程here,因为我必须为带有图像的列表视图做类似的事情,但原理很简单,因为您可以阅读那里显示的第一个示例类(由 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)。再从上面的代码sn -p 看一下整个线程。

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

      【讨论】:

      • 我的项目中没有 DefaultHttpClient。
      【解决方案12】:

      这里有很多很好的信息...我最近发现了一个名为 SmartImageView 的类,到目前为止它似乎运行良好。非常容易整合和使用。

      http://loopj.com/android-smart-image-view/

      https://github.com/loopj/android-smart-image-view

      更新:我最终写了一个blog post about this,所以请查看它以获取有关使用 SmartImageView 的帮助。

      第二次更新:我现在总是为此使用毕加索(见上文)并强烈推荐它。 :)

      【讨论】:

        【解决方案13】:

        这是一个迟到的回复,正如上面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 中添加以下权限以访问互联网。

        &lt;uses-permission android:name="android.permission.INTERNET" /&gt;

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

        【讨论】:

        • 这实际上非常适合极简主义!请记住,它需要在额外的Thread 中运行,因为 UI 线程不允许网络操作。
        • 收到错误 - 尝试在空对象引用上调用虚拟方法 'boolean android.widget.ImageView.post(java.lang.Runnable)'
        【解决方案14】:
        imageView.setImageBitmap(BitmapFactory.decodeStream(imageUrl.openStream()));//try/catch IOException and MalformedURLException outside
        

        【讨论】:

          【解决方案15】:

          这会帮助你...

          定义 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;
          }
          

          【讨论】:

            【解决方案16】:
                String img_url= //url of the image
                URL url=new URL(img_url);
                Bitmap bmp; 
                bmp=BitmapFactory.decodeStream(url.openConnection().getInputStream());
                ImageView iv=(ImageView)findviewById(R.id.imageview);
                iv.setImageBitmap(bmp);
            

            【讨论】:

              【解决方案17】:

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

              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();
              }
              

              【讨论】:

                【解决方案18】:
                    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;
                    } 
                

                【讨论】:

                  【解决方案19】:

                  一个简单而干净的方法是使用开源库Prime

                  【讨论】:

                    【解决方案20】:

                    这段代码已经过测试,完全可以运行。

                    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());
                    

                    【讨论】:

                      【解决方案21】:

                      适用于任何容器中的 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 感谢您提供完整、简单的解决方案。
                      【解决方案22】:

                      试试这个方法,希望能帮助你解决问题。

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

                      • 下载“AndroidQuery”库from here
                      • 将此 jar 复制/粘贴到项目 lib 文件夹,并将此库添加到项目构建路径中
                      • 现在我演示一下如何使用它。

                      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.
                      

                      【讨论】:

                        【解决方案23】:

                        Android Query 可以为您处理这些以及更多其他事情(例如缓存和加载进度)。

                        看看here

                        我认为是最好的方法。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-06-13
                          • 2013-07-10
                          • 2015-07-22
                          • 2014-02-08
                          • 1970-01-01
                          相关资源
                          最近更新 更多