从 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 中。 - 盖伊