在创建新的小部件时接收到比应该存在的更多的共享首选项

Receiving more shared preferences than should exist when creating new widget

我正在构建小部件,为您选择的值提供最佳货币汇率。在主页上,当我单击小部件和 select 我想要创建的小部件时,WidgetConfigure 应用程序应该会启动。 但是,它甚至在配置页面启动之前就崩溃了,我得到了这个错误:

java.lang.RuntimeException:java.lang.IndexOutOfBoundsException: Index: 2, Size: 2. 这是它引用的代码:

// Set the currencies for each object
        for(String currency: preferredCurrencies){
            currencyObjects.get(currencyCount).setCurrencyType(currency);
            currencyCount+=1;
        }

代码在我负责更新它的小部件方法之一中。

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetId, List<CurrencyObject> currencyObjects, Intent clickIntent) {
    theAppWidgetManager = appWidgetManager;
    // There may be multiple widgets active, so update all of them
    // Get the preferred Currencies
    Set<String> preferredCurrencies = AppWidgetConfigure.loadCurrencyPref(context,appWidgetId);

    // Inflate the layout
    RemoteViews view = new RemoteViews(context.getPackageName(), layout);
    // if the preferred Currencies have been declared already
    if(preferredCurrencies!= null){
        // Set the currencies for each object
        *for(String currency: preferredCurrencies){
            currencyObjects.get(currencyCount).setCurrencyType(currency);
            currencyCount+=1;
        }*
    }
    else{
        for(CurrencyObject curObj:currencyObjects){
            curObj.setCurrencyType("EUR");
        }
    }
    currencyCount = 0;

}

在我的小部件配置中 class 我有这些方法,我在其中设置了首选货币:

private static final String PREFS_NAME = "change.Widgets";
private static final String PREF_PREFIX_KEY = "appwidget_";
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private List<String> currencies = new ArrayList<>();
private int checkCounter;
private Set<String> chosenCurrencies = new TreeSet<>();

static void saveCurrencyPref(Context context, int appWidgetId, Set<String> chosenCurrencies) {
    SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
    prefs.putStringSet(PREF_PREFIX_KEY + appWidgetId, chosenCurrencies);
    prefs.apply();
}

static void deleteCurrencyPref(Context context, int appWidgetId) {
    SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
    prefs.remove(PREF_PREFIX_KEY + appWidgetId);
    prefs.apply();
}
public static Set<String> loadCurrencyPref(Context context, int appWidgetId) {
    SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
    Set chosenCurrencies = prefs.getStringSet(PREF_PREFIX_KEY + appWidgetId, null);
    return chosenCurrencies;
}

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    // Find the widget id from the intent.
    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    if (extras != null) {
        mAppWidgetId = extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    }
    // If this activity was started with an intent without an app widget ID, finish with an error.
    if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
        finish();
        return;
    }

    // Set the result to CANCELED.  This will cause the widget host to cancel
    // out of the widget placement if the user presses the back button.
    setResult(RESULT_CANCELED);

    // Create the layout with the checkboxes and the Button.
    setContentView(R.layout.widget_configure);
    LinearLayout ll = (LinearLayout) findViewById(R.id.configure_layout);
    TextView txt = new TextView(this);
    txt.setText("Must have: " + Integer.toString(checkBoxLimit) + " checkboxes");
    ll.addView(txt);
    // Create the checkboxes
    currencies.addAll(Arrays.asList(getResources().getStringArray(R.array.currency_array)));
    for(String item:currencies){
        CheckBox ch = new CheckBox(this);
        ch.setText(item);
        ll.addView(ch);
        ch.setOnCheckedChangeListener((cb, isChecked)->{
            //If it's checked and more than the allowed limit, don't consider it
            if(isChecked){
                if(checkCounter>=checkBoxLimit){
                    cb.setChecked(false);
                    Toast.makeText(this, txt.getText(), Toast.LENGTH_SHORT).show();
                }
                // If it's within the allowed limit, add to list of chosenCurrencies.
                else{
                    checkCounter+=1;
                    chosenCurrencies.add(cb.getText().toString());
                }
            }
            // If its, unchecked remove the currency from the list of chosenCurrencies.
            else{
                checkCounter-=1;
                chosenCurrencies.remove(cb.getText().toString());
            }
        });
    }
    // Create the button
    Button btn = new Button(this);
    btn.setText(R.string.apply);
    ll.addView(btn);

    // Finish this
    //Launch the widget once the button is pressed
    btn.setOnClickListener(v->{
        //If User selects right amount of checkboxes
        if(checkBoxLimit == checkCounter){
            final Context context = AppWidgetConfigure.this;

            // delete the previous currencies that existed there for that widget Id
            deleteCurrencyPref(context, mAppWidgetId);
            // Save the preferences
            saveCurrencyPref(context, mAppWidgetId, chosenCurrencies);
            // It is the responsibility of the configuration activity to update the app widget
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            int[] oneIdList = new int[1];
            oneIdList[0] = mAppWidgetId;
            //Update the current type of widget
            widget.onUpdate(context, appWidgetManager, oneIdList);
            // Make sure we pass back the original appWidgetId
            Intent resultValue = new Intent();
            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
            setResult(RESULT_OK, resultValue);
            finish();

        }
        else{
            Toast.makeText(this, txt.getText(), Toast.LENGTH_SHORT).show();
        }

    });

}
// Set the currencies for each object
                for (String currency : preferredCurrencies) {
                    if (currencyCount >= currencyObjects.size()) {
                        return
                    }
                    currencyObjects.get(currencyCount).setCurrencyType(currency);
                    currencyCount++;
                }

您的应用程序崩溃,因为您想要获取无效的列表项。例如,您的列表有 2 个项目,但您调用 list.get(2)