安卓天气APP:SharedPreferences数据已保存但书签页不显示问题求助
Hey there, let's break down why your saved weather locations aren't appearing in the bookmarked activity—even though Logcat says the data is saved. Looking through your SaveData class, I've spotted a few key issues and straightforward fixes:
1. Static List Isn't Updated After Saving
Your weatherHistoryList is a static ArrayList that gets initialized once in the SaveData constructor, but when you call saveWeatherList(), you're only writing to SharedPreferences—you don't update this static list. If your bookmarked activity is directly using SaveData.weatherHistoryList to display data, it'll show the old cached version instead of the new saved entries.
Fix: Update the static list inside saveWeatherList():
public void saveWeatherList(ArrayList<HistoryObj> objArray){ checkForNullKey(WEATHER_LIST_KEY); // Sync the static list with the new saved data weatherHistoryList = new ArrayList<>(objArray); Gson gson = new Gson(); ArrayList<String> objStrings = new ArrayList<String>(); for(HistoryObj obj : objArray){ objStrings.add(gson.toJson(obj)); } putListString(WEATHER_LIST_KEY, objStrings); }
2. Risky Separator Character
You're using the special character sequence ‚‗‚ to split/join your JSON strings. If any of your HistoryObj JSON serializations accidentally contain this sequence (unlikely but possible), TextUtils.split() will break your data into invalid chunks, leading to failed parsing.
Fix: Switch to a more robust, unlikely-to-appear separator like |||, and add null/empty checks:
// Define a safe separator as a constant private static final String LIST_SEPARATOR = "|||"; public ArrayList<String> getListString(String key) { String savedString = preferences.getString(key, ""); if (TextUtils.isEmpty(savedString)) { return new ArrayList<>(); } return new ArrayList<>(Arrays.asList(TextUtils.split(savedString, LIST_SEPARATOR))); } public void putListString(String key, ArrayList<String> stringList) { checkForNullKey(key); if (stringList == null || stringList.isEmpty()) { preferences.edit().putString(key, "").apply(); return; } String[] myStringList = stringList.toArray(new String[stringList.size()]); preferences.edit().putString(key, TextUtils.join(LIST_SEPARATOR, myStringList)).apply(); }
3. Static List & Instance Lifecycle Issues
If you're creating multiple SaveData instances across your app, each instance will overwrite the static weatherHistoryList with whatever's in SharedPreferences at the time of creation. This can lead to inconsistent data between screens.
Fix: Convert SaveData to a singleton to ensure only one instance exists:
private static SaveData instance; // Make constructor private to prevent multiple instances private SaveData(Context context){ int PRIVATE_MODE = 0; this.context = context.getApplicationContext(); // Use app context to avoid memory leaks preferences = context.getSharedPreferences(prefName,PRIVATE_MODE); editor = preferences.edit(); weatherHistoryList = getWeatherList(); } // Global access point public static SaveData getInstance(Context context){ if(instance == null){ instance = new SaveData(context); } return instance; }
4. Bookmarked Activity Data Loading
Ensure your bookmarked activity isn't just loading data once on startup. Refresh the list every time the activity comes into focus to get the latest saved data:
@Override protected void onResume() { super.onResume(); // Reload data from SaveData ArrayList<HistoryObj> bookmarkedLocations = SaveData.getInstance(this).getWeatherList(); // Update your RecyclerView/ListView adapter here yourAdapter.updateData(bookmarkedLocations); }
Bonus: Add Error Handling for JSON Parsing
Add try/catch blocks in getWeatherList() to catch any JSON parsing errors that might be silently failing:
public ArrayList<HistoryObj> getWeatherList(){ Gson gson = new Gson(); ArrayList<String> objStrings = getListString(WEATHER_LIST_KEY); ArrayList<HistoryObj> objects = new ArrayList<>(); if(objStrings != null && !objStrings.isEmpty()){ for(String jObjString : objStrings){ if(!TextUtils.isEmpty(jObjString)){ try { HistoryObj value = gson.fromJson(jObjString, HistoryObj.class); objects.add(value); } catch (JsonSyntaxException e) { Log.e(TAG, "Failed to parse weather object: " + jObjString, e); } } } } return objects; }
After applying these fixes, test saving a location again—your bookmarked activity should now display the saved entries correctly.
内容的提问来源于stack exchange,提问作者M B

