从小部件中的 URL 加载 ImageView
Loading an ImageView from an URL in a widget
我正在尝试制作一个具有 ImageView
的动态小部件。我正在尝试使用 AsyncTask
从 URL 下载图像,然后尝试将新下载的位图应用到 ImageView
,但小部件中没有显示任何内容。
这是小部件中的 Java 代码:
public class MyWidget extends AppWidgetProvider
{
private static RemoteViews remoteViews;
private static String thumbnailUrl = "..."; // The image I'd like to show
// Async task for downloading an image and setting it to the ImageView
class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
@Override
protected Bitmap doInBackground(String... urls)
{
String url = urls[0];
Bitmap icon = null;
try
{
InputStream in = new java.net.URL(urldisplay).openStream();
icon = BitmapFactory.decodeStream(in);
}
catch(Exception e)
{
e.printStackTrace();
}
return icon;
}
@Override
protected void onPostExecute(Bitmap bitmap)
{
if(bitmap == null)
{
System.out.println("Bitmap is null!");
return;
}
remoteViews.setImageViewBitmap(R.id.thumbnailView, bitmap);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager manager, int[] widgetIds)
{
if(remoteViews == null)
{
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
}
new DownloadImageTask().execute(thumbnailUrl);
}
} // End of MyWidget
小部件确实有效,因为如果我在那里放置静态 TextView
,它就会显示出来。然而,这个 ImageView
没有。视图的 ID 正确,URL 有效。调用 onPostExecute()
时位图不为空。为什么位图不显示?
检查你的 logcat 输出,你是否得到类似 -
ERROR/JavaBinder(20204): !!! FAILED BINDER TRANSACTION !!!
如果是,那么您已达到文件大小限制:P
首先,将 AsyncTask
替换为 IntentService
。在您完成工作之前,您的流程很可能会终止。将您的 AppWidgetProvider
委托给 IntentService
。
其次,使用比现有代码更好的代码来下载图像,因为它不能很好地处理典型的移动问题,例如偶发连接。有很多可用的图像加载库(Picasso、Universal Image Loader 等),它们在遇到问题时更有弹性。
第三,您实际上必须对 RemoteViews
做一些事情。现在,您调用 setImageViewBitmap()
... 然后将 RemoteViews
放在地板上。您需要 use AppWidgetManager
告诉 Android 使用 RemoteViews
.
更新应用小部件
而且,正如 Ashish 指出的那样,请记住 IPC 事务有 1MB 的限制,这将限制您的 Bitmap
可以达到的大小。许多这些图像加载库还内置了重采样逻辑,可以将图像缩放到合适的大小,因此您可以避免此限制。
我正在尝试制作一个具有 ImageView
的动态小部件。我正在尝试使用 AsyncTask
从 URL 下载图像,然后尝试将新下载的位图应用到 ImageView
,但小部件中没有显示任何内容。
这是小部件中的 Java 代码:
public class MyWidget extends AppWidgetProvider
{
private static RemoteViews remoteViews;
private static String thumbnailUrl = "..."; // The image I'd like to show
// Async task for downloading an image and setting it to the ImageView
class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
@Override
protected Bitmap doInBackground(String... urls)
{
String url = urls[0];
Bitmap icon = null;
try
{
InputStream in = new java.net.URL(urldisplay).openStream();
icon = BitmapFactory.decodeStream(in);
}
catch(Exception e)
{
e.printStackTrace();
}
return icon;
}
@Override
protected void onPostExecute(Bitmap bitmap)
{
if(bitmap == null)
{
System.out.println("Bitmap is null!");
return;
}
remoteViews.setImageViewBitmap(R.id.thumbnailView, bitmap);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager manager, int[] widgetIds)
{
if(remoteViews == null)
{
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
}
new DownloadImageTask().execute(thumbnailUrl);
}
} // End of MyWidget
小部件确实有效,因为如果我在那里放置静态 TextView
,它就会显示出来。然而,这个 ImageView
没有。视图的 ID 正确,URL 有效。调用 onPostExecute()
时位图不为空。为什么位图不显示?
检查你的 logcat 输出,你是否得到类似 -
ERROR/JavaBinder(20204): !!! FAILED BINDER TRANSACTION !!!
如果是,那么您已达到文件大小限制:P
首先,将 AsyncTask
替换为 IntentService
。在您完成工作之前,您的流程很可能会终止。将您的 AppWidgetProvider
委托给 IntentService
。
其次,使用比现有代码更好的代码来下载图像,因为它不能很好地处理典型的移动问题,例如偶发连接。有很多可用的图像加载库(Picasso、Universal Image Loader 等),它们在遇到问题时更有弹性。
第三,您实际上必须对 RemoteViews
做一些事情。现在,您调用 setImageViewBitmap()
... 然后将 RemoteViews
放在地板上。您需要 use AppWidgetManager
告诉 Android 使用 RemoteViews
.
而且,正如 Ashish 指出的那样,请记住 IPC 事务有 1MB 的限制,这将限制您的 Bitmap
可以达到的大小。许多这些图像加载库还内置了重采样逻辑,可以将图像缩放到合适的大小,因此您可以避免此限制。