Android使用服务更新两个小部件,AsyncTask仅更新最新的小部件

时间:2014-10-07 11:26:52

标签: android android-asynctask

目前我有一个下载和显示天气数据的小部件。当我将小部件放在主屏幕上,选择显示天气等的位置时,这很好。但是当我有两个活动的小部件,并且调用onUpdate时,只有最新的要添加的小部件会被更新。

WeatherWidget:

public class WeatherWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) { 

    //Creating and adding pending intents to each widget, then calling
    //updateWeather();

    super.onUpdate(context, appWidgetManager, appWidgetIds);
    }     

    private void updateWeather(Context context,
            AppWidgetManager appWidgetManager, int[] appWidgetIds, int appWidgetId) {
        Intent serviceIntent = new Intent(context, WeatherService.class);
        serviceIntent.putExtra("widgetId", appWidgetId);
        context.startService(serviceIntent);
    }
}

的WeatherService:

public class WeatherService extends Service {

    private int widgetId;
    private String choice;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        widgetId = intent.getExtras().getInt("widgetId");
        SharedPreferences settings = getSharedPreferences("WeatherPrefs",
                MODE_PRIVATE);

        //"choice" is a string that contains which location to get weather data from
        choice = settings.getString(String.valueOf(widgetId) + "s", "def");

        initialize(choice);
        return Service.START_NOT_STICKY;
    }

    public void initialize(String choice) {

        switch (choice) {
        case "Choice1":
            try {
                URL url = new URL(
                        "http://www.myurl1");
                AsyncTask task = new WeatherRetriever().execute(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }

            break;

        case "Choice2":
            try {
                URL url = new URL(
                        "http://www.myurl2");
                AsyncTask task = new WeatherRetriever().execute(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            break;

        case "Choice3":
            try {
                URL url = new URL(
                        "http://www.myurl3");
                AsyncTask task = new WeatherRetriever().execute(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            break;

        case "Choice4":
            try {
                URL url = new URL(
                        "http://www.myurl4");
                AsyncTask task = new WeatherRetriever().execute(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            break;

        case "Choice5":
            try {
                URL url = new URL(
                        "http://www.myurl5");
                AsyncTask task = new WeatherRetriever().execute(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            break;
        }
    }
}

AsyncTask WeatherRetriever从给定的URL下载天气数据,onPostExecute调用此方法:

    private void updateWidget() {
        AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(getApplicationContext());

        //Collects the data from the result of WeahterRetriever here, code removed

        RemoteViews remoteViews = new RemoteViews(getApplicationContext()
                .getPackageName(), R.layout.mywidget);

        //Set up the result for the remove view here, code removed

        appWidgetManager.updateAppWidget(widgetId, remoteViews);

    }

这里的问题是,当我有两个小部件同时处于活动状态时,它们几乎在同一时间启动服务。在AsyncTask能够完成第一个小部件之前,第二个小部件已经调用了startService,并更改了widgetId的值。我该如何防止这种情况?

马库斯

1 个答案:

答案 0 :(得分:1)

您可以尝试将小部件ID存储在数组中,并通过小部件中的onDestroy调用将其移除到您的服务中吗?