从 URL 显示图像到 Android 应用程序

Posted

技术标签:

【中文标题】从 URL 显示图像到 Android 应用程序【英文标题】:Display image from URLto Android app 【发布时间】: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#。

谢谢

【问题讨论】:

【参考方案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 的图像下载库 - Picasso 或 Glide。您可以在 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

以上是关于从 URL 显示图像到 Android 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Android:无法从mysql数据库中检索图像URL并将其显示在imageView中

如何转换图像 base64 并使用 url 从服务器上传到项目?

从 android 客户端将图像存储到 Blobstore 并检索 blobkey 并上传 url 以存储在 Datastore 中。 - 盖伊

如何从 URL 下载图像并缓存 Android (React-Native)

Android - 将图像从 URL 保存到 SD 卡

如何通过蓝牙接收图像