I wasn't happy with the long load times, so I figured out a way to quickly load a placeholder image, and then load the thumbnails in an AsyncTask, and then call notifyAppWidgetViewDataChanged() once to refresh the appwidget after they are all loaded. This results in instant appearance of the data without the images, and is a pretty good solution for my application. I used a boolean value in my RemoteViewsFactory to indicate if I had already downloaded the data with no images, so the it wouldn't get stuck in an endless refresh cycle.
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();
}