Обновить 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);
} 
Другие вопросы по тегам