【问题标题】:Display image from URLto Android app从 URL 显示图像到 Android 应用程序
【发布时间】:2018-03-05 11:52:15
【问题描述】:

我正在尝试将来自特定 URL 的图像显示到我的 Android 应用程序中的图像视图。我正在尝试使用可用于此问题的答案 here 但我的代码中遇到了一个愚蠢的错误:

public static Drawable LoadImageFromWebOperations(String url) {
try {
    InputStream ss = (InputStream) new URL(url).getContent(); // here is the error saying that "There is no argument given that corresponds to the required formal parameter 'types' of 'URL.GetContent(Class [])"
    Drawable d = Drawable.createFromStream(ss, "src name"); // and another error here saying: Cannot convert from 'Java.IO.InputStream' to 'System.IO.Stream'
    return d;
} catch (Exception e) {
    return null;
}
}

第一个错误:“没有给出与 'URL.GetContent(Class []) 所需的形式参数'types'相对应的参数”

第二个错误:“无法从 'Java.IO.InputStream' 转换为 'System.IO.Stream'”

所以我搜索了另一种解决方案,我找到了这个:

URL url = new URL("http://image10.bizrate-images.com/resizesq=60&uid=2216744464");
Bitmap bmp = 
BitmapFactory.decodeStream(url.openConnection().getInputStream());
imageView.setImageBitmap(bmp);

但我也遇到了openconnection()getInputStream 的错误。 请告诉我如何解决我的问题,或者如果您有其他特定于 c# 用户的解决方案,请告诉我。

注意:我在 Visual Studio 中使用 c#。

谢谢

【问题讨论】:

    标签: c# android image visual-studio url


    【解决方案1】:

    使用Glide

    GlideApp
        .with(this)
        .load("http://image10.bizrate-images.com/resizesq=60&uid=2216744464")
        .into(imageView);
    

    Glide 是一个快速高效的开源媒体管理和图像 Android 的加载框架,包含媒体解码、内存和 磁盘缓存和资源池化成简单易用 界面。

    【讨论】:

    • 我尝试使用它,我收到一个错误:当前上下文中不存在 Glide。我需要下载一些库吗?
    • 是的,在你的 gradle 依赖中添加这些行:compile 'com.github.bumptech.glide:glide:4.1.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
    • 我在 Visual Studio 中使用 xamarin,没有 gradle 依赖项。所以我已经从 nuget 下载了 Xamarin.Gradle,现在我得到了这个 error
    【解决方案2】:

    如果您想要更小的应用程序并且在图像加载中需要的功能非常少,那么 Picasso 是最好的选择。但如果您想要更多的自定义、动画 GIF 支持和更好的内存管理,那么您可以继续使用 Glide 库。

    这是两者的代码。

    毕加索:

     Picasso.with(context)
     .load(url)
     .centerCrop()
     .placeholder(R.drawable.loading_spinner)
     .into(myImageView);
    

    滑翔

    Glide.with(context)
    .load(url)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .crossFade()
    .into(myImageView);
    

    【讨论】:

      【解决方案3】:

      最快的方法:

      您可以尝试这些适用于 Android 的图像下载库 - PicassoGlide。您可以在 Fragment 或 Activity 或 Adapter 中使用其中一个:

      毕加索

      // .with() only takes Context objects
      Picasso.with(context)
             .load("http://image10.bizrate-images.com/resizesq=60&uid=2216744464")
             .into(imageView);
      

      滑行

      // .with() can take Context, Activity, Fragment or FragmentActivity objects.
      Glide.with(context)
             .load("http://image10.bizrate-images.com/resizesq=60&uid=2216744464")
             .into(imageView);
      

      这里有一个link,它解释了两个库之间的异同。


      另一种方法:

      它涉及创建一个服务来获取数据(在后台线程上),将 url 保存到位图中,最后将该位图发送回 UI 线程以保存在 ImageView 中。

      步骤:

      • 创建服务(并添加到清单中)。
      • Service 应该扩展 IntentService(并实现 onHandleIntent)。
      • 从意图中检索 url。
      • 从 url 获取图片。
      • 将网址解码并保存到位图。
      • 将位图放在EventBus 中以发送到 UI 线程。
      • 将位图设置为 ImageView。

      清单:

      <application
          ...
      
          <activity android:name=".MainActivity">
              ...
          </activity>
      
          <service android:name=".ImageFetchService" />
      
      </application>
      

      Eventbus 依赖项(Android Studio 的 gradle,Visual Studio 的 Naxam-EventBus.Droid):

      dependencies {
          //
          compile 'org.greenrobot:eventbus:3.0.0'
      }
      
      Install-Package Naxam.EventBus.Droid // Use this instead since Xamarin.Android doesn't have gradle.
      

      服务类:

      public class ImageFetchService extends IntentService {
      
          public ImageFetchService() {
              super("ImageFetchService");
          }
      
          @Override
          protected void onHandleIntent(@Nullable Intent intent) {
              String urlString = intent.getData().toString();
      
              URL url;
      
              try {
                  url = new URL(urlString);
                  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                  connection.connect();
                  InputStream input = connection.getInputStream();
                  Bitmap myBitmap = BitmapFactory.decodeStream(input);
      
                  BitmapEvent bitmapEvent = new BitmapEvent();
                  bitmapEvent.setBitmap(myBitmap);
                  EventBus.getDefault().post(bitmapEvent);
              } catch (java.io.IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

      现在,我们需要一个类来封装从我们的服务类发送的位图对象。 EventBus 传输也称为 events 的对象,这些事件可以在其中包含任意数量的其他对象 - 将 EventBus 视为将 POJO(或事件)从一个地方传输到另一个地方的总线。

      在这种情况下,EventBus 会将我们的位图从后台线程传输到 UI 线程。

      BitmapEvent 类(EventBus 的 POJO):

      public class BitmapEvent {
      
          private Bitmap bitmap;
      
          public BitmapEvent() {
              //
          }
      
          public Bitmap getBitmap() {
              return bitmap;
          }
      
          public void setBitmap(Bitmap bitmap) {
              this.bitmap = bitmap;
          }
      }
      

      主活动:

      public class MainActivity extends AppCompatActivity {
      
          ImageView imageView;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              imageView = findViewById(R.id.image);
      
              String urlString = "http://image10.bizrate-images.com/resizesq=60&uid=2216744464";
      
              Intent fetchImageIntent = new Intent(this, ImageFetchService.class);
              fetchImageIntent.setData(Uri.parse(urlString));
              startService(fetchImageIntent);
          }
      
          @Override
          protected void onStart() {
              super.onStart();
              EventBus.getDefault().register(this);
          }
      
          @Override
          protected void onStop() {
              super.onStop();
              EventBus.getDefault().unregister(this);
          }
      
          @Subscribe(threadMode = ThreadMode.MAIN)
          public void getBitmapEvent(BitmapEvent bitmapEvent) {
              imageView.setImageBitmap(bitmapEvent.getBitmap());
          }
      }
      

      注意:根据您的互联网连接和图像的大小,您可能会注意到在 ImageView 使用位图更新之前存在一些延迟。

      您可以查看 AsyncTask 作为 EventBus 的替代方案。

      【讨论】:

      • 我在使用 Glide error 时遇到此错误。对于毕加索,我收到错误消息,说我必须使用 okhttp 和 okhttp.urlconnection 但是当我使用它们时,我得到了这个错误; java.lang.IllegalArgumentException: 已添加:Lcom/squareup/okhttp/Address,还有这个; 'Resource.Designer.cs',因为它正被另一个进程使用。我做什么?
      • 对于 glide 的问题,下载 Glide.Xamarin nuget 库,然后尝试添加以下依赖项:Xamarin.Android.Support.Annotations (>= 25.4.0.2) 和 Xamarin.Android.Support。 v4 (>= 25.4.0.2)
      • 我下载了 Xamarin.Android.Support.v4 并尝试下载第二个,但出现此错误:无法安装包 'Xamarin.Android.Support.Annotations 25.4 .0.2'。您正在尝试将此包安装到以“MonoAndroid,Version=v6.0”为目标的项目中,但该包不包含任何与该框架兼容的程序集引用或内容文件
      • 它可能只支持 Android 7.0 及更高版本,是否可以尝试将您应用的目标框架设置为 Android 7.0(API 级别 24)或更高版本?如果可能,请尝试安装 7.0 SDK (MonoAndroid70) 并将编译设置为最新版本(或 7.0)。
      • 我成功下载了它,但我仍然收到这个错误:java.lang.IllegalArgumentException: already added : Lcom/squareup/okhttp/Address
      猜你喜欢
      • 2017-06-12
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多