Обновить Android-виджет (с помощью асинхронной задачи) с изображением из Интернета
У меня есть простой виджет Android, который я хочу обновить с помощью изображения из Интернета. Я могу отображать статические изображения на виджете без проблем. Мне сказали, что для этого вам нужно использовать асинхронную задачу, и у меня нет большого опыта с этим.
Вот мой виджет:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++){
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main);
//Setup a static image, this works fine.
views.setImageViewResource(R.id.imageView1, R.drawable.wordpress_icon);
new DownloadBitmap().execute("MyTestString");
appWidgetManager.updateAppWidget(appWidgetId, views);
}
Затем у меня есть класс асинхронных задач, который выполняет загрузку. Это выглядит так:
public class DownloadBitmap extends AsyncTask<String, Void, Bitmap> {
/** The url from where to download the image. */
private String url = "http://0.tqn.com/d/webclipart/1/0/5/l/4/floral-icon-5.jpg";
@Override
protected Bitmap doInBackground(String... params) {
try {
InputStream in = new java.net.URL(url).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
//NOTE: it is not thread-safe to set the ImageView from inside this method. It must be done in onPostExecute()
} catch (Exception e) {
Log.e("ImageDownload", "Download failed: " + e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
//Here is where I should set the image to the imageview, but how?
}
}
Я думаю, что мой код успешно загрузил изображение из Интернета.
Что меня смущает, так это то, как я могу получить это изображение в "ImageView" конкретного виджета из моего класса задач Async. Чтобы обновить изображение, вам нужен доступ к 3 различным объектам: Context, AppWidgetManager и AppWidgetId.... Но как мне передать все эти объекты внутри этого оператора:???
new DownloadBitmap().execute("MyTestString");
Спасибо!
2 ответа
Одним из решений было бы передать RemoteViews
в качестве аргумента DownloadBitmap
конструктор, а в onPostExecute()
установить изображение:
В onUpdate():
new DownloadBitmap(views).execute("MyTestString");
и в DownloadBitmap:
//....
public class DownloadBitmap extends AsyncTask<String, Void, Bitmap> {
private RemoteViews views;
public DownloadBitmap(RemoteViews views){
this.views = views;
}
//.....
public void onPostExecute(Bitmap bitmap){
views.setImageViewBitmap(R.id.imageView1, bitmap);
}
}
Пожалуйста, смотрите решение Энди Рес выше. Я немного подправил, чтобы передать больше параметров... но это работает!!!!
Я называю это так:
new DownloadBitmap(views, appWidgetId, appWidgetManager).execute("MyTestString");
тогда моя задача начинается так:
public class DownloadBitmap extends AsyncTask<String, Void, Bitmap> {
/** The url from where to download the image. */
private String url = "http://0.tqn.com/d/webclipart/1/0/5/l/4/floral-icon-5.jpg";
private RemoteViews views;
private int WidgetID;
private AppWidgetManager WidgetManager;
public DownloadBitmap(RemoteViews views, int appWidgetID, AppWidgetManager appWidgetManager){
this.views = views;
this.WidgetID = appWidgetID;
this.WidgetManager = appWidgetManager;
}
@Override
protected Bitmap doInBackground(String... params) {
try {
InputStream in = new java.net.URL(url).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
Log.v("ImageDownload", "download succeeded");
Log.v("ImageDownload", "Param 0 is: " + params[0]);
return bitmap;
//NOTE: it is not thread-safe to set the ImageView from inside this method. It must be done in onPostExecute()
} catch (Exception e) {
Log.e("ImageDownload", "Download failed: " + e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
views.setImageViewBitmap(R.id.imageView1, bitmap);
WidgetManager.updateAppWidget(WidgetID, views);
}