Я пытаюсь сохранить SparseArray в базе данных Room и не могу его скомпилировать. Я получаю сообщение об ошибке «Не уверен, как преобразовать курсор в тип возвращаемого значения этого метода» вместе с «Запрос возвращает некоторые столбцы [plannerLineData], которые не используются android.util.SparseArray.»
Я пытался использовать только одно поле в объекте PlannerLine с отдельным классом PlannerLineData.
У меня есть преобразователи данных для преобразования SparseArray в String и преобразования String обратно в SparseArray.
Я проверил несколько вопросов по stackoverflow и успешно использовал конвертеры Date to Long и Long to Date в других проектах, но мне кажется, что-то где-то не хватает.
Файлы данных:
@Entity
public class PlannerLine implements Serializable {
private static final long serialVersionUID = 1L;
@TypeConverters(Converters.class)
@PrimaryKey
@SerializedName("planner_line")
@NonNull
public SparseArray plannerLineData;
public SparseArray getPlannerLineData() {
return plannerLineData;
}
public void setPlannerLineData(SparseArray plannerLineData) {
this.plannerLineData = plannerLineData;
}
public class PlannerLineData implements Serializable {
@SerializedName("lineId")
public int lineId;
@SerializedName("plan_text")
public String planText;
public int getLineId() {
return lineId;
}
public void setLineId(int lineId) {
this.lineId = lineId;
}
public String getPlanText() {
return planText;
}
public void setPlanText(String planText) {
this.planText = planText;
}
}
Проблемная область DAO:
@Dao
public interface PlannerDao {
@Query("SELECT * from PlannerLine")
public SparseArray getPlannerLine(); <---Doesn't like this line
Я также пытался вернуть SparseArray<PlannerLine>
и SparseArray<PlannerLineData>
, но без радости.
Класс преобразователей:
public class Converters {
@TypeConverter
public static String sparseArrayToString(SparseArray sparseArray) {
if (sparseArray == null) {
return null;
}
int size = sparseArray.size();
if (size <= 0) {
return "{}";
}
StringBuilder buffer = new StringBuilder(size * 28);
buffer.append('{');
for (int i = 0; i < size; i++) {
if (i > 0) {
buffer.append("-,- ");
}
int key = sparseArray.keyAt(i);
buffer.append(key);
buffer.append("-=-");
Object value = sparseArray.valueAt(i);
buffer.append(value);
}
buffer.append('}');
return buffer.toString();
}
@TypeConverter
public static SparseArray stringToSparseArray(String string) {
if (string == null) {
return null;
}
String entrySeparator = "-=-";
String elementSeparator = "-,-";
SparseArray sparseArray = new SparseArray();
String[] entries = StringUtils.splitByWholeSeparator(string, elementSeparator);
for (int i = 0; i < entries.length; i++) {
String[] parts = StringUtils.splitByWholeSeparator(entries[i], entrySeparator);
int key = Integer.parseInt(parts[0]);
String text = parts[1];
sparseArray.append(key, text);
}
return sparseArray;
}
Предложения будут оценены. Спасибо
Edit:
Мое первоначальное видение этого приложения состояло в том, чтобы хранить все линии плана в одной SparseArray
вместе с двумя дополнительными SparseIntArrays
(о которых я раньше не упоминал, поскольку решение будет похоже на SparseArray
) для содержит информацию о том, как линии плана взаимодействуют друг с другом.
Прочитав полезные ответы @ dglozano, я решил переделать приложение, чтобы просто хранить обычные файлы БД в Room и загружать данные в SparseArray
(и два SparseIntArrays
) при запуске, использовать только в памяти SparseArray
и SparseIntArrays
, пока приложение активно, затем записать изменения в разреженных массивах в БД во время onStop()
. Я также рассматриваю возможность обновления БД в фоновом режиме при работе через приложение.
Поскольку ответы и предложения, предоставленные @dglozano, привели меня к решению о перепроектировании, я принимаю его ответ как решение.
Спасибо за помощь.