Мне нужно сохранить данные на SharedPreferences таким образом, чтобы у меня был такой объект:
{
"days": [
{
"exercises": [
{
"name": "Bench Press",
"sets": 3,
"reps": 8
},
{
"name": "Skull Crushers",
"sets": 3,
"reps": 8
},
{
"name": "Flys",
"sets": 3,
"reps": 8
}
]
},
{
"exercises": [
{
"name": "Bench Press",
"sets": 3,
"reps": 8
},
{
"name": "Skull Crushers",
"sets": 3,
"reps": 8
},
{
"name": "Flys",
"sets": 3,
"reps": 8
}
]
}
]
}
Мне нужно будет оттянуть от объекта и добавить к объекту. Я знаю, что вы не можете сохранять карты на SharedPreferences. Я начинаю думать, что лучше всего использовать ObjectOutputStream, но я не уверен, что это лучший вариант для использования внутренней памяти. Думаю, я просто ищу совета относительно моих лучших вариантов.
edit: из того, что сказал Advice-Dog, я думаю, что лучше всего использовать gson. Значит ли это, что когда я хочу (например) добавить еще одно упражнение ко второму индексу «дней», я сначала беру объект из настроек, конвертирую его из gson в объект, затем добавляю упражнение, а затем конвертирую его обратно на gson, а потом перезаписать настройки? Я не говорю, что это плохо, я просто хочу знать, нужно ли это делать и целесообразно ли это.




При сохранении более сложных типов в Android я бы предложил использовать gson. Gson - это библиотека синтаксического анализа JSON от Google, и даже если вы не используете JSON, вы можете преобразовать свой Objects в строку JSON и легко сохранить ее.
Например, вы можете преобразовать свой список Objects в String следующим образом.
val list : List<MyObject> // ... add items to your list
// Convert to JSON
val string = gson.toJson(list)
// Store it into Shared Preferences
preferences.putString("list", string).apply()
И тогда вы можете легко вернуть его в такой список.
// Fetch the JSON
val string = preferences.getString("list", "")
// Convert it back into a List
val list: List<MyObject> = gson.fromJson(string, object : TypeToken<List<MyObject>>() {}.type)
Просто вопрос. Означает ли это, что каждый раз, когда я хочу добавить значение к объекту, я сначала конвертирую json в объект, затем добавляю значение, затем конвертирую его обратно в json, а затем сохраняю предыдущие настройки?
@BUInvent Да. Это может показаться расточительным, но это нормально. GSON работает очень быстро, как и SharedPreferences. Вы также можете сохранить локальную копию, обновить ее и сохранить. Таким образом, вы не перечитываете его постоянно, но все зависит от вашего использования.
Использование JSON - лучшее решение, но вот еще одно решение (просто чтобы добавить еще один способ решения проблемы):
вы можете использовать такие общие ключи настроек:
for((dayIndex, day) in days.withIndex)
for((exeIndex, exe) in day)
for((key, value) in exe)
addExercise(day = dayIndex, exercise = exeIndex, key = key, value = value)
fun addExercise(day: String, exercise: String, key: String, value: String) =
preferences.putString("day${day}_exe${exercise}_${key}", value).apply()
тогда вы можете получить название первого упражнения из Второй день следующим образом:
val first_exercise_second_day = preferences.getString("day2_exe1_name")
и вы можете добавить упражнение к третьему дню следующим образом:
addExercise(day = "3", exercise = "1", key = "name", value = "Flys")
addExercise(day = "3", exercise = "1", key = "sets", value = "5")
addExercise(day = "3", exercise = "1", key = "reps", value = "3")
Но чтобы найти пустой день или пустой номер упражнения, вам нужно получить все ключи общих предпочтений и использовать регулярное выражение или циклы.
вы можете использовать библиотеку для google ==> Gson добавить это в зависимости в gradle
implementation 'com.google.code.gson:gson:2.8.0'
вы можете этой библиотекой преобразовать объект в json как String, затем вы можете сохранить его в общем Pref As String когда вы получаете String из Pref, вы можете преобразовать String в объект
преобразовать json в модель
/*type of model*/=new Gson().fromJson(/*json string*/,/*type of model*/)
преобразовать модель в json как String
new Gson().toJson(/*model you want to convert */)===> return String
должен моделировать ту же иерархию для json, где возникают проблемы при преобразовании
Модель для вас json должна быть похожей на эту модель
public class JSONModel implements Serializable {
@SerializedName("days")
private List<Day> mDays;
public List<Day> getDays() {
return mDays;
}
public void setDays(List<Day> days) {
mDays = days;
}
public class Day {
@SerializedName("exercises")
private List<Exercise> mExercises;
public List<Exercise> getExercises() {
return mExercises;
}
public void setExercises(List<Exercise> exercises) {
mExercises = exercises;
}
}
public class Exercise {
@SerializedName("name")
private String mName;
@SerializedName("reps")
private Long mReps;
@SerializedName("sets")
private Long mSets;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public Long getReps() {
return mReps;
}
public void setReps(Long reps) {
mReps = reps;
}
public Long getSets() {
return mSets;
}
public void setSets(Long sets) {
mSets = sets;
}
}
}
у этой структуры данных есть проблема в том, что нельзя различать дни - и
SharedPreferencesскорее предназначены для хранения настроек приложения (простых данных); не использовать в качестве базы данных.