我正在尝试使用AsyncTask从Google I/O调整模式以从网络下载图像并将它们放入AppWidget中的ListView项目中。除了this post之外,我没有找到很多资源来做这样的事情。
问题是,海报没有集合视图,只有一个项目。当我尝试遵循该模式时,每次onPostExecute()运行时,整个appwidget仅使用单个列表项进行更新,而不是我需要的。如果在onPostExecute()中删除对updateAppWidget()的调用,则不会更新视图,我猜是因为必须发生进程间通信。我不确定从哪里开始,有人可以帮忙吗?
这是我对AsyncTask的定义:
public ThumbnailAsyncTask(RemoteViews rv, int appWidgetID, AppWidgetManager appWidgetManager)
{
mTarget = rv;
this.widgetID = appWidgetID;
this.widgetManager = appWidgetManager;
}
@Override
protected Bitmap doInBackground(String... params)
{
String url = params[0];
return getBitmapFromURL(url);
}
@Override
protected void onPostExecute(Bitmap result)
{
mTarget.setImageViewBitmap(R.id.thumbnail, result);
widgetManager.updateAppWidget(widgetID, mTarget);
}
private Bitmap getBitmapFromURL(String str)
{
Bitmap bmp = null;
HttpURLConnection connection = null;
try
{
URL url = new URL(str);
connection = openConnectionWithTimeout(url);
bmp = BitmapFactory.decodeStream(connection.getInputStream());
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
connection.disconnect();
}
return bmp;
}
}
和RemoteViewsFactory中的getViewAt():
public RemoteViews getViewAt(int position)
{
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.list_item);
ArrayList<ResultDetails> mResults = mJSONParser.getResults();
if (mResults.get(position).hasHeading())
rv.setTextViewText(R.id.title, mResults.get(position).getHeading());
if (mResults.get(position).hasBody())
rv.setTextViewText(R.id.description, mResults.get(position).getBody(true));
if (mResults.get(position).hasTimestamp())
rv.setTextViewText(R.id.date, mResults.get(position).getTimestamp(true));
Bundle extras = new Bundle();
extras.putString(LINK_ITEM, mResults.get(position).getExternalURL());
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.list_item, fillInIntent);
if (mResults.get(position).hasThumbnailURL())
{
AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
new ThumbnailAsyncTask(rv, mAppWidgetId, mgr).execute(mResults.get(position).getThumbnailURL());
}
return rv;
}
答案 0 :(得分:1)
我对加载时间过长感到不满意,所以我找到了一种方法来快速加载占位符图像,然后在AsyncTask中加载缩略图,然后调用notifyAppWidgetViewDataChanged()一次以刷新appwidget全部加载。这样可以在没有图像的情况下立即显示数据,对我的应用程序来说是一个非常好的解决方案。我在我的RemoteViewsFactory中使用了一个布尔值来指示我是否已经下载了没有图像的数据,因此它不会陷入无休止的刷新周期。
class ThumbnailAsyncTask extends AsyncTask<Void, Void, Void>
{
private AppWidgetManager widgetManager;
private List<ResultDetails> details;
private Context context;
public ThumbnailAsyncTask(AppWidgetManager
appWidgetManager, List<ResultDetails> details, Context context)
{
this.details = details;
this.context = context;
this.widgetManager = appWidgetManager;
}
@Override
protected Void doInBackground(Void... params)
{
for (ResultDetails item : details)
{
if (item.hasThumbnailURL())
{
item.setThumbnail(getBitmapFromURL(item.getThumbnailURL()));
}
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
widgetManager.notifyAppWidgetViewDataChanged(widgetManager.getAppWidgetIds(
new ComponentName(context, WidgetProvider.class)), R.id.list_view);
}
public RemoteViews getViewAt(int position)
{
RemoteViews rv;
rv = new RemoteViews(mContext.getPackageName(), R.layout.list_item);
ArrayList<ResultDetails> mResults = mSearchResultsGenerator.getResults();
ResultDetails result = mResults.get(position);
if (result.hasHeading())
rv.setTextViewText(R.id.title, result.getHeading());
if (result.hasBody())
rv.setTextViewText(R.id.description, result.getBody(true));
if (result.hasTimestamp())
rv.setTextViewText(R.id.date, result.getTimestamp(true));
if (result.hasPrice())
rv.setTextViewText(R.id.price, result.getPrice());
Bundle extras = new Bundle();
extras.putString(LINK_ITEM, result.getExternalURL());
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.list_item, fillInIntent);
if (result.hasThumbnail())
{
rv.setImageViewBitmap(R.id.thumbnail, result.getThumbnail());
}
else
{
rv.setImageViewBitmap(R.id.thumbnail, noImageBitmap);
}
return rv;
}
public void onDataSetChanged()
{
if (isOnline(mContext))
{
if (!hasData)
{
mSearchResultsGenerator.generate();
if (mSearchResultsGenerator.isUpdateSucceeded())
{
AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
hasData = true;
new ThumbnailAsyncTask(mgr, mSearchResultsGenerator.getResults(), mContext).execute();
}
else
makeNoConnectionToast();
}
else
{
}
}
else
makeNoConnectionToast();
}
答案 1 :(得分:0)
我相信您需要调用AppWidgetManager.notifyAppWidgetViewDataChanged()
来刷新AppWidget中的集合视图