在创建新的小部件时接收到比应该存在的更多的共享首选项
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)
我正在构建小部件,为您选择的值提供最佳货币汇率。在主页上,当我单击小部件和 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)